feat: added error handling and knowledge base provider support
This commit is contained in:
parent
3fc7911c97
commit
6384525e20
@ -573,6 +573,7 @@
|
|||||||
"directory_placeholder": "Enter Directory Path",
|
"directory_placeholder": "Enter Directory Path",
|
||||||
"model_info": "Model Info",
|
"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",
|
"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"
|
"source": "Source"
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
|
|||||||
@ -556,7 +556,11 @@
|
|||||||
"sitemap_placeholder": "サイトマップURLを入力",
|
"sitemap_placeholder": "サイトマップURLを入力",
|
||||||
"directories": "ディレクトリ",
|
"directories": "ディレクトリ",
|
||||||
"add_directory": "ディレクトリを追加",
|
"add_directory": "ディレクトリを追加",
|
||||||
"directory_placeholder": "ディレクトリパスを入力"
|
"directory_placeholder": "ディレクトリパスを入力",
|
||||||
|
"model_info": "モデル情報",
|
||||||
|
"not_support": "ナレッジベースデータベースエンジンが更新されました。このナレッジベースはもうサポートされていません。新しいナレッジベースを作成してください",
|
||||||
|
"no_provider": "ナレッジベースモデルプロバイダーが設定されていません。ナレッジベースはもうサポートされていません。新しいナレッジベースを作成してください",
|
||||||
|
"source": "ソース"
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
"pinned": "固定済み",
|
"pinned": "固定済み",
|
||||||
|
|||||||
@ -573,6 +573,7 @@
|
|||||||
"directory_placeholder": "Введите путь к директории",
|
"directory_placeholder": "Введите путь к директории",
|
||||||
"model_info": "Модель информации",
|
"model_info": "Модель информации",
|
||||||
"not_support": "База знаний базы данных движок обновлен, база знаний больше не поддерживается, пожалуйста, создайте новую базу знаний",
|
"not_support": "База знаний базы данных движок обновлен, база знаний больше не поддерживается, пожалуйста, создайте новую базу знаний",
|
||||||
|
"no_provider": "База знаний модель поставщика не настроена, база знаний больше не поддерживается, пожалуйста, создайте новую базу знаний",
|
||||||
"source": "Источник"
|
"source": "Источник"
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
|
|||||||
@ -562,6 +562,7 @@
|
|||||||
"directory_placeholder": "请输入目录路径",
|
"directory_placeholder": "请输入目录路径",
|
||||||
"model_info": "模型信息",
|
"model_info": "模型信息",
|
||||||
"not_support": "知识库数据库引擎已更新,该知识库将不再支持,请重新创建知识库",
|
"not_support": "知识库数据库引擎已更新,该知识库将不再支持,请重新创建知识库",
|
||||||
|
"no_provider": "知识库模型服务商丢失,该知识库将不再支持,请重新创建知识库",
|
||||||
"source": "来源"
|
"source": "来源"
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
|
|||||||
@ -561,6 +561,7 @@
|
|||||||
"directory_placeholder": "請輸入目錄路徑",
|
"directory_placeholder": "請輸入目錄路徑",
|
||||||
"model_info": "模型信息",
|
"model_info": "模型信息",
|
||||||
"not_support": "知識庫數據庫引擎已更新,該知識庫將不再支持,請重新創建知識庫",
|
"not_support": "知識庫數據庫引擎已更新,該知識庫將不再支持,請重新創建知識庫",
|
||||||
|
"no_provider": "知識庫模型提供商遺失,該知識庫將不再支持,請重新創建知識庫",
|
||||||
"source": "來源"
|
"source": "來源"
|
||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
|
|||||||
@ -391,6 +391,7 @@ const Container = styled(Scrollbar)`
|
|||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
|
padding-bottom: 10px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const Label = styled.p`
|
const Label = styled.p`
|
||||||
@ -410,7 +411,7 @@ const SettingRowTitleSmall = styled(SettingRowTitle)`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export const SettingGroup = styled.div<{ theme?: ThemeMode }>`
|
export const SettingGroup = styled.div<{ theme?: ThemeMode }>`
|
||||||
padding: 10px 5px;
|
padding: 0 5px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup'
|
|||||||
import { isLocalAi } from '@renderer/config/env'
|
import { isLocalAi } from '@renderer/config/env'
|
||||||
import { isVisionModel } from '@renderer/config/models'
|
import { isVisionModel } from '@renderer/config/models'
|
||||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||||
import { getProviderByModel } from '@renderer/services/AssistantService'
|
import { getProviderName } from '@renderer/services/ProviderService'
|
||||||
import { Assistant } from '@renderer/types'
|
import { Assistant } from '@renderer/types'
|
||||||
import { Button } from 'antd'
|
import { Button } from 'antd'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
@ -31,13 +31,14 @@ const SelectModelButton: FC<Props> = ({ assistant }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const providerName = getProviderName(model?.provider)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownButton size="small" type="default" onClick={onSelectModel}>
|
<DropdownButton size="small" type="default" onClick={onSelectModel}>
|
||||||
<ButtonContent>
|
<ButtonContent>
|
||||||
<ModelAvatar model={model} size={20} />
|
<ModelAvatar model={model} size={20} />
|
||||||
<ModelName>
|
<ModelName>
|
||||||
{model ? model.name : t('button.select_model')} |{' '}
|
{model ? model.name : t('button.select_model')} {providerName ? '| ' + providerName : ''}
|
||||||
{t(`provider.${model?.provider}`, { defaultValue: getProviderByModel(model)?.name })}
|
|
||||||
</ModelName>
|
</ModelName>
|
||||||
{isVisionModel(model) && <VisionIcon style={{ marginLeft: 0 }} />}
|
{isVisionModel(model) && <VisionIcon style={{ marginLeft: 0 }} />}
|
||||||
</ButtonContent>
|
</ButtonContent>
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import TextEditPopup from '@renderer/components/Popups/TextEditPopup'
|
|||||||
import Scrollbar from '@renderer/components/Scrollbar'
|
import Scrollbar from '@renderer/components/Scrollbar'
|
||||||
import { useKnowledge } from '@renderer/hooks/useKnowledge'
|
import { useKnowledge } from '@renderer/hooks/useKnowledge'
|
||||||
import FileManager from '@renderer/services/FileManager'
|
import FileManager from '@renderer/services/FileManager'
|
||||||
|
import { getProviderName } from '@renderer/services/ProviderService'
|
||||||
import { FileType, FileTypes, KnowledgeBase } from '@renderer/types'
|
import { FileType, FileTypes, KnowledgeBase } from '@renderer/types'
|
||||||
import { Alert, Button, Card, Divider, message, Tag, Typography, Upload } from 'antd'
|
import { Alert, Button, Card, Divider, message, Tag, Typography, Upload } from 'antd'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
@ -74,11 +75,17 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
addDirectory
|
addDirectory
|
||||||
} = useKnowledge(selectedBase.id || '')
|
} = useKnowledge(selectedBase.id || '')
|
||||||
|
|
||||||
|
const providerName = getProviderName(base?.model.provider || '')
|
||||||
|
const disabled = !base?.version || !providerName
|
||||||
|
|
||||||
if (!base) {
|
if (!base) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleAddFile = () => {
|
const handleAddFile = () => {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const input = document.createElement('input')
|
const input = document.createElement('input')
|
||||||
input.type = 'file'
|
input.type = 'file'
|
||||||
input.multiple = true
|
input.multiple = true
|
||||||
@ -91,6 +98,10 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleDrop = async (files: File[]) => {
|
const handleDrop = async (files: File[]) => {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (files) {
|
if (files) {
|
||||||
const _files: FileType[] = files.map((file) => ({
|
const _files: FileType[] = files.map((file) => ({
|
||||||
id: file.name,
|
id: file.name,
|
||||||
@ -110,6 +121,10 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleAddUrl = async () => {
|
const handleAddUrl = async () => {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const url = await PromptPopup.show({
|
const url = await PromptPopup.show({
|
||||||
title: t('knowledge_base.add_url'),
|
title: t('knowledge_base.add_url'),
|
||||||
message: '',
|
message: '',
|
||||||
@ -135,6 +150,10 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleAddSitemap = async () => {
|
const handleAddSitemap = async () => {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const url = await PromptPopup.show({
|
const url = await PromptPopup.show({
|
||||||
title: t('knowledge_base.add_sitemap'),
|
title: t('knowledge_base.add_sitemap'),
|
||||||
message: '',
|
message: '',
|
||||||
@ -160,16 +179,28 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleAddNote = async () => {
|
const handleAddNote = async () => {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const note = await TextEditPopup.show({ text: '', textareaProps: { rows: 20 } })
|
const note = await TextEditPopup.show({ text: '', textareaProps: { rows: 20 } })
|
||||||
note && addNote(note)
|
note && addNote(note)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEditNote = async (note: any) => {
|
const handleEditNote = async (note: any) => {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const editedText = await TextEditPopup.show({ text: note.content as string, textareaProps: { rows: 20 } })
|
const editedText = await TextEditPopup.show({ text: note.content as string, textareaProps: { rows: 20 } })
|
||||||
editedText && updateNoteContent(note.id, editedText)
|
editedText && updateNoteContent(note.id, editedText)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleAddDirectory = async () => {
|
const handleAddDirectory = async () => {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const path = await window.api.file.selectFolder()
|
const path = await window.api.file.selectFolder()
|
||||||
console.log('[KnowledgeContent] Selected directory:', path)
|
console.log('[KnowledgeContent] Selected directory:', path)
|
||||||
path && addDirectory(path)
|
path && addDirectory(path)
|
||||||
@ -180,10 +211,13 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
{!base?.version && (
|
{!base?.version && (
|
||||||
<Alert message={t('knowledge_base.not_support')} type="error" style={{ marginBottom: 20 }} showIcon />
|
<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>
|
<FileSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('files.title')}</Title>
|
<Title level={5}>{t('files.title')}</Title>
|
||||||
<Button icon={<PlusOutlined />} onClick={handleAddFile}>
|
<Button icon={<PlusOutlined />} onClick={handleAddFile} disabled={disabled}>
|
||||||
{t('knowledge_base.add_file')}
|
{t('knowledge_base.add_file')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
@ -223,7 +257,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.directories')}</Title>
|
<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')}
|
{t('knowledge_base.add_directory')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
@ -250,7 +284,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.urls')}</Title>
|
<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')}
|
{t('knowledge_base.add_url')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
@ -277,7 +311,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.sitemaps')}</Title>
|
<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')}
|
{t('knowledge_base.add_sitemap')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
@ -304,7 +338,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
<ContentSection>
|
<ContentSection>
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
<Title level={5}>{t('knowledge_base.notes')}</Title>
|
<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')}
|
{t('knowledge_base.add_note')}
|
||||||
</Button>
|
</Button>
|
||||||
</TitleWrapper>
|
</TitleWrapper>
|
||||||
@ -332,11 +366,15 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
<label htmlFor="model-info">{t('knowledge_base.model_info')}</label>
|
<label htmlFor="model-info">{t('knowledge_base.model_info')}</label>
|
||||||
<Tag color="blue">{base.model.name}</Tag>
|
<Tag color="blue">{base.model.name}</Tag>
|
||||||
<Tag color="cyan">{t('models.dimensions', { dimensions: base.dimensions || 0 })}</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>
|
</ModelInfo>
|
||||||
|
|
||||||
<IndexSection>
|
<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')}
|
{t('knowledge_base.search')}
|
||||||
</Button>
|
</Button>
|
||||||
</IndexSection>
|
</IndexSection>
|
||||||
|
|||||||
15
src/renderer/src/services/ProviderService.ts
Normal file
15
src/renderer/src/services/ProviderService.ts
Normal 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
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user