From 34ebab0af869cfb90103cbbc2416fc4e783fbe2d Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Wed, 25 Dec 2024 17:31:11 +0800 Subject: [PATCH] refactor: knowledge base database engine --- .github/workflows/release.yml | 4 +- ...embedjs-libsql-npm-0.1.25-fad000d74c.patch | 25 - ...-tools-embedjs-npm-0.1.25-ec5645cf36.patch | 17 + electron.vite.config.ts | 12 +- package.json | 7 +- scripts/after-pack.js | 25 +- scripts/build-npm.js | 28 + scripts/download-npm.js | 14 - scripts/utils.js | 50 +- src/main/services/FileStorage.ts | 2 - src/main/services/KnowledgeService.ts | 24 +- .../src/components/ListItem/index.tsx | 46 +- .../src/components/Popups/PromptPopup.tsx | 17 +- src/renderer/src/config/prompts.ts | 15 +- src/renderer/src/i18n/locales/en-us.json | 10 +- src/renderer/src/i18n/locales/ru-ru.json | 10 +- src/renderer/src/i18n/locales/zh-cn.json | 10 +- src/renderer/src/i18n/locales/zh-tw.json | 10 +- .../src/pages/knowledge/KnowledgeContent.tsx | 26 +- .../src/pages/knowledge/KnowledgePage.tsx | 13 +- .../components/AddKnowledgePopup.tsx | 31 +- src/renderer/src/providers/AiProvider.ts | 10 +- .../src/providers/AnthropicProvider.ts | 4 + src/renderer/src/providers/BaseProvider.ts | 7 +- src/renderer/src/providers/GeminiProvider.ts | 13 +- src/renderer/src/providers/OpenAIProvider.ts | 8 + src/renderer/src/queue/KnowledgeQueue.ts | 2 +- src/renderer/src/services/AssistantService.ts | 2 +- src/renderer/src/services/KnowledgeService.ts | 11 +- src/renderer/src/types/index.ts | 2 + yarn.lock | 542 ++++++++++-------- 31 files changed, 614 insertions(+), 383 deletions(-) delete mode 100644 .yarn/patches/@llm-tools-embedjs-libsql-npm-0.1.25-fad000d74c.patch create mode 100644 .yarn/patches/@llm-tools-embedjs-npm-0.1.25-ec5645cf36.patch create mode 100644 scripts/build-npm.js delete mode 100644 scripts/download-npm.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d40050c..5f52b0ee 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,7 +49,7 @@ jobs: - name: Build Linux if: matrix.os == 'ubuntu-latest' run: | - yarn download:npm linux + yarn build:npm linux yarn build:linux env: @@ -58,7 +58,7 @@ jobs: - name: Build Mac if: matrix.os == 'macos-latest' run: | - yarn download:npm darwin + yarn build:npm mac yarn build:mac env: CSC_LINK: ${{ secrets.CSC_LINK }} diff --git a/.yarn/patches/@llm-tools-embedjs-libsql-npm-0.1.25-fad000d74c.patch b/.yarn/patches/@llm-tools-embedjs-libsql-npm-0.1.25-fad000d74c.patch deleted file mode 100644 index 0c794bfa..00000000 --- a/.yarn/patches/@llm-tools-embedjs-libsql-npm-0.1.25-fad000d74c.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/src/libsql-db.js b/src/libsql-db.js -index 58c42e4910bd0e53bc497ff9b9702b1f7a961266..c02351dc95ba36fc4db97ddfb69206539fb4de1c 100644 ---- a/src/libsql-db.js -+++ b/src/libsql-db.js -@@ -41,9 +41,9 @@ export class LibSqlDb { - } - async similaritySearch(query, k) { - const statement = `SELECT id, pageContent, uniqueLoaderId, source, metadata, -- vector_distance_cos(vector, vector32('[${query.join(',')}]')) -+ vector_distance_cos(vector, vector32('[${query.join(',')}]')) as distance - FROM ${this.tableName} -- ORDER BY vector_distance_cos(vector, vector32('[${query.join(',')}]')) ASC -+ ORDER BY distance DESC - LIMIT ${k};`; - this.debug(`Executing statement - ${truncateCenterString(statement, 700)}`); - const results = await this.client.execute(statement); -@@ -52,7 +52,7 @@ export class LibSqlDb { - return { - metadata, - pageContent: result.pageContent.toString(), -- score: 1, -+ score: 1 - result.distance, - }; - }); - } diff --git a/.yarn/patches/@llm-tools-embedjs-npm-0.1.25-ec5645cf36.patch b/.yarn/patches/@llm-tools-embedjs-npm-0.1.25-ec5645cf36.patch new file mode 100644 index 00000000..3b6d373e --- /dev/null +++ b/.yarn/patches/@llm-tools-embedjs-npm-0.1.25-ec5645cf36.patch @@ -0,0 +1,17 @@ +diff --git a/src/core/rag-embedding.js b/src/core/rag-embedding.js +index 50c3c4064af17bc4c7c46554d8f2419b3afceb0e..632c9b2e04d2e0e3bb09ef1cd8f29d2560e6afc1 100644 +--- a/src/core/rag-embedding.js ++++ b/src/core/rag-embedding.js +@@ -1,10 +1,8 @@ + export class RAGEmbedding { + static singleton; + static async init(embeddingModel) { +- if (!this.singleton) { +- await embeddingModel.init(); +- this.singleton = new RAGEmbedding(embeddingModel); +- } ++ await embeddingModel.init(); ++ this.singleton = new RAGEmbedding(embeddingModel); + } + static getInstance() { + return RAGEmbedding.singleton; diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 9dc98420..c9b3311e 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -20,7 +20,7 @@ export default defineConfig({ '@llm-tools/embedjs-loader-xml', '@llm-tools/embedjs-loader-pdf', '@llm-tools/embedjs-loader-sitemap', - '@llm-tools/embedjs-libsql' + '@llm-tools/embedjs-lancedb' ] }), ...visualizerPlugin('main') @@ -34,9 +34,8 @@ export default defineConfig({ }, build: { rollupOptions: { - external: ['@libsql/client'] - }, - minify: true + external: ['@lancedb/lancedb'] + } } }, preload: { @@ -51,10 +50,7 @@ export default defineConfig({ } }, optimizeDeps: { - exclude: ['chunk-7UIZINC5.js', 'chunk-7OJJKI46.js'] - }, - build: { - minify: true + exclude: [] } } }) diff --git a/package.json b/package.json index 82aa6b5b..a693381d 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "typecheck": "npm run typecheck:node && npm run typecheck:web", "start": "electron-vite preview", "dev": "electron-vite dev", - "download:npm": "node scripts/download-npm.js", "build": "npm run typecheck && electron-vite build", "postinstall": "electron-builder install-app-deps", "build:unpack": "dotenv npm run build && electron-builder --dir", @@ -37,6 +36,7 @@ "build:linux": "dotenv electron-vite build && electron-builder --linux", "build:linux:arm64": "dotenv electron-vite build && electron-builder --linux --arm64", "build:linux:x64": "dotenv electron-vite build && electron-builder --linux --x64", + "build:npm": "node scripts/build-npm.js", "release": "node scripts/version.js", "publish": "yarn release patch push", "pulish:artifacts": "cd packages/artifacts && npm publish && cd -", @@ -49,8 +49,8 @@ "@electron-toolkit/preload": "^3.0.0", "@electron-toolkit/utils": "^3.0.0", "@electron/notarize": "^2.5.0", - "@llm-tools/embedjs": "^0.1.25", - "@llm-tools/embedjs-libsql": "patch:@llm-tools/embedjs-libsql@npm%3A0.1.25#~/.yarn/patches/@llm-tools-embedjs-libsql-npm-0.1.25-fad000d74c.patch", + "@llm-tools/embedjs": "patch:@llm-tools/embedjs@npm%3A0.1.25#~/.yarn/patches/@llm-tools-embedjs-npm-0.1.25-ec5645cf36.patch", + "@llm-tools/embedjs-lancedb": "^0.1.25", "@llm-tools/embedjs-loader-csv": "^0.1.25", "@llm-tools/embedjs-loader-markdown": "^0.1.25", "@llm-tools/embedjs-loader-msoffice": "^0.1.25", @@ -61,6 +61,7 @@ "@llm-tools/embedjs-openai": "^0.1.25", "@types/react-infinite-scroll-component": "^5.0.0", "adm-zip": "^0.5.16", + "apache-arrow": "^18.1.0", "docx": "^9.0.2", "electron-log": "^5.1.5", "electron-store": "^8.2.0", diff --git a/scripts/after-pack.js b/scripts/after-pack.js index d14e24da..8c2d6643 100644 --- a/scripts/after-pack.js +++ b/scripts/after-pack.js @@ -9,29 +9,34 @@ exports.default = async function (context) { const arch = context.arch if (platform === 'mac') { - const nodeModulesPath = path.join( + const node_modules_path = path.join( context.appOutDir, 'Cherry Studio.app', 'Contents', 'Resources', 'app.asar.unpacked', - 'node_modules', - '@libsql' + 'node_modules' ) - keepLibsqlNodeModules(nodeModulesPath, arch === Arch.arm64 ? ['darwin-arm64'] : ['darwin-x64']) + removeDifferentArchNodeFiles( + node_modules_path, + '@lancedb', + arch === Arch.arm64 ? ['lancedb-darwin-arm64'] : ['lancedb-darwin-x64'] + ) } if (platform === 'linux') { - const nodeModulesPath = path.join(context.appOutDir, 'resources', 'app.asar.unpacked', 'node_modules', '@libsql') - keepLibsqlNodeModules( - nodeModulesPath, - arch === Arch.arm64 ? ['linux-arm64-gnu', 'linux-arm64-musl'] : ['linux-x64-gnu', 'linux-x64-musl'] - ) + const node_modules_path = path.join(context.appOutDir, 'resources', 'app.asar.unpacked', 'node_modules') + const _arch = + arch === Arch.arm64 + ? ['lancedb-linux-arm64-gnu', 'lancedb-linux-arm64-musl'] + : ['lancedb-linux-x64-gnu', 'lancedb-linux-x64-musl'] + removeDifferentArchNodeFiles(node_modules_path, '@lancedb', _arch) } } -function keepLibsqlNodeModules(modulePath, arch) { +function removeDifferentArchNodeFiles(nodeModulesPath, packageName, arch) { + const modulePath = path.join(nodeModulesPath, packageName) const dirs = fs.readdirSync(modulePath) dirs .filter((dir) => !arch.includes(dir)) diff --git a/scripts/build-npm.js b/scripts/build-npm.js new file mode 100644 index 00000000..95ff0e93 --- /dev/null +++ b/scripts/build-npm.js @@ -0,0 +1,28 @@ +const { downloadNpmPackage } = require('./utils') + +async function downloadNpm(platform) { + if (!platform || platform === 'mac') { + downloadNpmPackage( + '@lancedb/lancedb-darwin-arm64', + 'https://registry.npmjs.org/@lancedb/lancedb-darwin-arm64/-/lancedb-darwin-arm64-0.14.0.tgz' + ) + downloadNpmPackage( + '@lancedb/lancedb-darwin-x64', + 'https://registry.npmjs.org/@lancedb/lancedb-darwin-x64/-/lancedb-darwin-x64-0.14.0.tgz' + ) + } + + if (!platform || platform === 'linux') { + downloadNpmPackage( + '@lancedb/lancedb-linux-arm64-gnu', + 'https://registry.npmjs.org/@lancedb/lancedb-linux-arm64-gnu/-/lancedb-linux-arm64-gnu-0.14.0.tgz' + ) + downloadNpmPackage( + '@lancedb/lancedb-linux-x64-gnu', + 'https://registry.npmjs.org/@lancedb/lancedb-linux-x64-gnu/-/lancedb-linux-x64-gnu-0.14.0.tgz' + ) + } +} + +const platformArg = process.argv[2] +downloadNpm(platformArg) diff --git a/scripts/download-npm.js b/scripts/download-npm.js deleted file mode 100644 index 605f38fe..00000000 --- a/scripts/download-npm.js +++ /dev/null @@ -1,14 +0,0 @@ -const { downloadNpmPackage } = require('./utils') - -async function downloadNpm(platform) { - if (!platform || platform === 'darwin') { - downloadNpmPackage('@libsql', '0.4.7', 'darwin', ['arm64', 'x64']) - } - - if (!platform || platform === 'linux') { - downloadNpmPackage('@libsql', '0.4.7', 'linux', ['arm64-gnu', 'x64-gnu']) - } -} - -const platformArg = process.argv[2] -downloadNpm(platformArg) diff --git a/scripts/utils.js b/scripts/utils.js index 4e3edb4b..4d2eb7ca 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -2,37 +2,33 @@ const fs = require('fs') const path = require('path') const os = require('os') -function downloadNpmPackage(package, version, platform, architectures = ['x64', 'arm64']) { +function downloadNpmPackage(packageName, url) { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'npm-download-')) - for (const arch of architectures) { - const targetDir = path.join('./node_modules/', package, `${platform}-${arch}`) + const targetDir = path.join('./node_modules/', packageName) + const filename = packageName.replace('/', '-') + '.tgz' - // Skip if directory already exists - if (fs.existsSync(targetDir)) { - console.log(`${targetDir} already exists, skipping download...`) - continue - } - - const filename = path.join(tempDir, `${platform}-${arch}-${version}.tgz`) - const url = `https://registry.npmjs.org/${package}/${platform}-${arch}/-/${platform}-${arch}-${version}.tgz` - - try { - console.log(`Downloading ${filename}...`, url) - const { execSync } = require('child_process') - execSync(`curl --fail -o ${filename} ${url}`) - - console.log(`Extracting ${filename}...`) - execSync(`tar -xvf ${filename}`) - execSync(`rm -rf ${filename}`) - execSync(`mv package ${targetDir}`) - } catch (error) { - console.error(`Error processing ${filename}: ${error.message}`) - if (fs.existsSync(filename)) { - fs.unlinkSync(filename) - } - throw error + // Skip if directory already exists + if (fs.existsSync(targetDir)) { + console.log(`${targetDir} already exists, skipping download...`) + return + } + + try { + console.log(`Downloading ${packageName}...`, url) + const { execSync } = require('child_process') + execSync(`curl --fail -o ${filename} ${url}`) + + console.log(`Extracting ${filename}...`) + execSync(`tar -xvf ${filename}`) + execSync(`rm -rf ${filename}`) + execSync(`mv package ${targetDir}`) + } catch (error) { + console.error(`Error processing ${packageName}: ${error.message}`) + if (fs.existsSync(filename)) { + fs.unlinkSync(filename) } + throw error } fs.rmSync(tempDir, { recursive: true, force: true }) diff --git a/src/main/services/FileStorage.ts b/src/main/services/FileStorage.ts index dff78863..2ef4af4c 100644 --- a/src/main/services/FileStorage.ts +++ b/src/main/services/FileStorage.ts @@ -56,8 +56,6 @@ class FileStorage { const storedFilePath = path.join(this.storageDir, file) const storedStats = fs.statSync(storedFilePath) - console.debug('storedFilePath', storedFilePath) - if (storedStats.size === fileSize) { const [originalHash, storedHash] = await Promise.all([ this.getFileHash(filePath), diff --git a/src/main/services/KnowledgeService.ts b/src/main/services/KnowledgeService.ts index a0cf38d6..3b1a516e 100644 --- a/src/main/services/KnowledgeService.ts +++ b/src/main/services/KnowledgeService.ts @@ -3,7 +3,7 @@ import path from 'node:path' import { LocalPathLoader, RAGApplication, RAGApplicationBuilder, TextLoader } from '@llm-tools/embedjs' import { AddLoaderReturn, ExtractChunkData } from '@llm-tools/embedjs-interfaces' -import { LibSqlDb } from '@llm-tools/embedjs-libsql' +import { LanceDb } from '@llm-tools/embedjs-lancedb' import { MarkdownLoader } from '@llm-tools/embedjs-loader-markdown' import { DocxLoader, ExcelLoader, PptLoader } from '@llm-tools/embedjs-loader-msoffice' import { PdfLoader } from '@llm-tools/embedjs-loader-pdf' @@ -26,8 +26,13 @@ class KnowledgeService { } } - private getRagApplication = async ({ id, model, apiKey, baseURL }: KnowledgeBaseParams): Promise => { - console.debug('getRagApplication', path.join(this.storageDir, id)) + private getRagApplication = async ({ + id, + model, + apiKey, + baseURL, + dimensions + }: KnowledgeBaseParams): Promise => { return new RAGApplicationBuilder() .setModel('NO_MODEL') .setEmbeddingModel( @@ -35,19 +40,16 @@ class KnowledgeService { model, apiKey, configuration: { baseURL }, - dimensions: 1024, - batchSize: 10 + dimensions, + batchSize: 20 }) ) - .setVectorDatabase(new LibSqlDb({ path: path.join(this.storageDir, id) })) + .setVectorDatabase(new LanceDb({ path: path.join(this.storageDir, id) })) .build() } - public create = async ( - _: Electron.IpcMainInvokeEvent, - { id, model, apiKey, baseURL }: KnowledgeBaseParams - ): Promise => { - this.getRagApplication({ id, model, apiKey, baseURL }) + public create = async (_: Electron.IpcMainInvokeEvent, base: KnowledgeBaseParams): Promise => { + this.getRagApplication(base) } public reset = async (_: Electron.IpcMainInvokeEvent, { base }: { base: KnowledgeBaseParams }): Promise => { diff --git a/src/renderer/src/components/ListItem/index.tsx b/src/renderer/src/components/ListItem/index.tsx index e4e31a24..da999be9 100644 --- a/src/renderer/src/components/ListItem/index.tsx +++ b/src/renderer/src/components/ListItem/index.tsx @@ -5,15 +5,20 @@ interface ListItemProps { active?: boolean icon?: ReactNode title: string + subtitle?: string onClick?: () => void } -const ListItem = ({ active, icon, title, onClick }: ListItemProps) => { +const ListItem = ({ active, icon, title, subtitle, onClick }: ListItemProps) => { + const borderRadius = subtitle ? '10px' : '16px' return ( - + - {icon && {icon}} - {title} + {icon && {icon}} + + {title} + {subtitle && {subtitle}} + ) @@ -42,11 +47,38 @@ const ListItemContainer = styled.div` ` const ListItemContent = styled.div` - display: -webkit-box; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; + display: flex; + align-items: center; + gap: 8px; overflow: hidden; font-size: 13px; ` +const IconWrapper = styled.span` + margin-right: 8px; +` + +const TextContainer = styled.div` + display: flex; + flex-direction: column; + overflow: hidden; +` + +const TitleText = styled.div` + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +` + +const SubtitleText = styled.div` + font-size: 10px; + color: var(--color-text-soft); + margin-top: 2px; + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; + color: var(--color-text-3); +` + export default ListItem diff --git a/src/renderer/src/components/Popups/PromptPopup.tsx b/src/renderer/src/components/Popups/PromptPopup.tsx index 519bd10f..c6fe6ddb 100644 --- a/src/renderer/src/components/Popups/PromptPopup.tsx +++ b/src/renderer/src/components/Popups/PromptPopup.tsx @@ -14,7 +14,7 @@ interface PromptPopupShowParams { } interface Props extends PromptPopupShowParams { - resolve: (value: string) => void + resolve: (value: any) => void } const PromptPopupContainer: React.FC = ({ @@ -30,18 +30,21 @@ const PromptPopupContainer: React.FC = ({ const onOk = () => { setOpen(false) + resolve(value) } - const handleCancel = () => { + const onCancel = () => { setOpen(false) } const onClose = () => { - resolve(value) + resolve(null) } + PromptPopup.hide = onCancel + return ( - + {message} = ({ ) } +const TopViewKey = 'PromptPopup' + export default class PromptPopup { static topviewId = 0 static hide() { - TopView.hide('PromptPopup') + TopView.hide(TopViewKey) } static show(props: PromptPopupShowParams) { return new Promise((resolve) => { @@ -69,7 +74,7 @@ export default class PromptPopup { {...props} resolve={(v) => { resolve(v) - this.hide() + TopView.hide(TopViewKey) }} />, 'PromptPopup' diff --git a/src/renderer/src/config/prompts.ts b/src/renderer/src/config/prompts.ts index 2ccd4f73..7043d3b7 100644 --- a/src/renderer/src/config/prompts.ts +++ b/src/renderer/src/config/prompts.ts @@ -50,23 +50,12 @@ export const SUMMARIZE_PROMPT = export const TRANSLATE_PROMPT = 'You are a translation expert. Translate from input language to {{target_language}}, provide the translation result directly without any explanation and keep original format. Do not translate if the target language is the same as the source language.' -export const REFERENCE_PROMPT = `请根据参考资料回答问题,并使用脚注格式引用数据来源。参考资料可能和问题无关,请忽略无关的参考资料。 +export const REFERENCE_PROMPT = `请根据参考资料回答问题,并使用脚注格式引用数据来源。请忽略无关的参考资料。 ## 脚注格式: 1. **脚注标记**:在正文中使用 [^数字] 的形式标记脚注,例如 [^1]。 -2. **脚注内容**:在文档末尾使用 [^数字]: 脚注内容 的形式定义脚注的具体内容。 - -## 脚注示例和要求: - -1. type 为 file 时:[^1]: [__name__](http://file/__url__) -2. type 为 directory 时:[^1]: [__name__](http://file/__url__) -3. type 为 url,sitemap 时:[^1]: [__name__](__url__) -4. type 为 note 时:[^1]: __note__ - -__url__ 替换成参考资料的 url -__name__ 请根据参考资料的 url 进行解析和替换 -__note__ 请根据参考资料的 content 进行总结和替换 +2. **脚注内容**:在文档末尾使用 [^数字]: 脚注内容 的形式定义脚注的具体内容 ## 我的问题是: diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index f69f6ff1..d86fab27 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -248,7 +248,8 @@ "upgrade.success.content": "Please restart the application to complete the upgrade", "upgrade.success.title": "Upgrade successfully", "regenerate.confirm": "Regenerating will replace current message", - "copy.success": "Copied!" + "copy.success": "Copied!", + "get_embedding_dimensions": "Failed to get embedding dimensions" }, "minapp": { "title": "MinApp" @@ -559,7 +560,9 @@ "sitemap_placeholder": "Enter Website Map URL", "directories": "Directories", "add_directory": "Add Directory", - "directory_placeholder": "Enter Directory Path" + "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" }, "models": { "pinned": "Pinned", @@ -577,7 +580,8 @@ "free": "Free", "embedding": "Embedding", "embedding_model": "Embedding Model", - "embedding_model_tooltip": "Add in Settings->Model Provider->Manage" + "embedding_model_tooltip": "Add in Settings->Model Provider->Manage", + "dimensions": "Dimensions {{dimensions}}" } } } diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 159d95e4..e952f093 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -248,7 +248,8 @@ "upgrade.success.content": "Пожалуйста, перезапустите приложение для завершения обновления", "upgrade.success.title": "Обновление успешно", "regenerate.confirm": "Перегенерация заменит текущее сообщение", - "copy.success": "Скопировано!" + "copy.success": "Скопировано!", + "get_embedding_dimensions": "Не удалось получить размерность встраивания" }, "minapp": { "title": "Встроенные приложения" @@ -559,7 +560,9 @@ "sitemap_placeholder": "Введите URL карты сайта", "directories": "Директории", "add_directory": "Добавить директорию", - "directory_placeholder": "Введите путь к директории" + "directory_placeholder": "Введите путь к директории", + "model_info": "Модель информации", + "not_support": "База знаний базы данных движок обновлен, база знаний больше не поддерживается, пожалуйста, создайте новую базу знаний" }, "models": { "pinned": "Закреплено", @@ -577,7 +580,8 @@ "free": "Бесплатные модели", "embedding": "Встраиваемые модели", "embedding_model": "Встраиваемые модели", - "embedding_model_tooltip": "Добавьте в настройки->модель сервиса->управление" + "embedding_model_tooltip": "Добавьте в настройки->модель сервиса->управление", + "dimensions": "{{dimensions}} мер" } } } diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 1e188369..81580f7a 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -249,7 +249,8 @@ "upgrade.success.content": "重启用以完成升级", "upgrade.success.title": "升级成功", "regenerate.confirm": "重新生成会覆盖当前消息", - "copy.success": "复制成功" + "copy.success": "复制成功", + "get_embedding_dimensions": "获取嵌入维度失败" }, "minapp": { "title": "小程序" @@ -548,7 +549,9 @@ "sitemap_placeholder": "请输入站点地图 URL", "directories": "目录", "add_directory": "添加目录", - "directory_placeholder": "请输入目录路径" + "directory_placeholder": "请输入目录路径", + "model_info": "模型信息", + "not_support": "知识库数据库引擎已更新,该知识库将不再支持,请重新创建知识库" }, "models": { "pinned": "已固定", @@ -566,7 +569,8 @@ "free": "免费模型", "embedding": "嵌入模型", "embedding_model": "嵌入模型", - "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加" + "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加", + "dimensions": "{{dimensions}} 维" } } } diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index b7f1939f..b75ea246 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -248,7 +248,8 @@ "upgrade.success.content": "請重新啟動應用以完成升級", "upgrade.success.title": "升級成功", "regenerate.confirm": "重新生成會覆蓋當前訊息", - "copy.success": "複製成功" + "copy.success": "複製成功", + "get_embedding_dimensions": "獲取嵌入維度失敗" }, "minapp": { "title": "小程序" @@ -547,7 +548,9 @@ "sitemap_placeholder": "請輸入網站地圖 URL", "directories": "目錄", "add_directory": "添加目錄", - "directory_placeholder": "請輸入目錄路徑" + "directory_placeholder": "請輸入目錄路徑", + "model_info": "模型信息", + "not_support": "知識庫數據庫引擎已更新,該知識庫將不再支持,請重新創建知識庫" }, "models": { "pinned": "已固定", @@ -565,7 +568,8 @@ "free": "免費模型", "embedding": "嵌入模型", "embedding_model": "嵌入模型", - "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加" + "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加", + "dimensions": "{{dimensions}} 維" } } } diff --git a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx index 64691e25..d9c54c82 100644 --- a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx +++ b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx @@ -14,7 +14,7 @@ import Scrollbar from '@renderer/components/Scrollbar' import { useKnowledge } from '@renderer/hooks/useKnowledge' import FileManager from '@renderer/services/FileManager' import { FileType, FileTypes, KnowledgeBase } from '@renderer/types' -import { Button, Card, message, Typography, Upload } from 'antd' +import { Alert, Button, Card, Divider, message, Tag, Typography, Upload } from 'antd' import { FC } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -177,6 +177,9 @@ const KnowledgeContent: FC = ({ selectedBase }) => { return ( + {!base.dimensions && ( + + )} {t('files.title')} @@ -323,6 +326,15 @@ const KnowledgeContent: FC = ({ selectedBase }) => { + + + + + {base.model.name} + {t('models.dimensions', { dimensions: base.dimensions || 0 })} + {base.model.provider} + +