diff --git a/bun.lockb b/bun.lockb
index ce5cb65..a4deaa6 100644
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index d9a126b..98f5370 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
"langchain": "^0.1.28",
"lucide-react": "^0.350.0",
"ml-distance": "^4.0.1",
- "pdfjs-dist": "^4.0.379",
+ "pdfjs-dist": "4.0.379",
"property-information": "^6.4.1",
"pubsub-js": "^1.9.4",
"react": "18.2.0",
diff --git a/src/assets/locale/en/settings.json b/src/assets/locale/en/settings.json
index a2b35a0..589f557 100644
--- a/src/assets/locale/en/settings.json
+++ b/src/assets/locale/en/settings.json
@@ -41,12 +41,12 @@
"confirm": "Are you sure you want to delete your chat history? This action cannot be undone."
},
"export": {
- "label": "Export Chat History, Settings, and Prompts",
+ "label": "Export Chat History, Knowledge Base, and Prompts",
"button": "Export Data",
"success": "Export Success"
},
"import": {
- "label": "Import Chat History, Settings, and Prompts",
+ "label": "Import Chat History, Knowledge Base, and Prompts",
"button": "Import Data",
"success": "Import Success",
"error": "Import Error"
diff --git a/src/assets/locale/ja-JP/settings.json b/src/assets/locale/ja-JP/settings.json
index 34c8a99..1fae4f5 100644
--- a/src/assets/locale/ja-JP/settings.json
+++ b/src/assets/locale/ja-JP/settings.json
@@ -44,12 +44,12 @@
"confirm": "チャット履歴を削除してもよろしいですか?この操作は元に戻せません。"
},
"export": {
- "label": "チャット履歴、設定、プロンプトをエクスポートする",
+ "label": "チャット履歴、知識ベース、プロンプトをエクスポート",
"button": "データをエクスポート",
"success": "エクスポート成功"
},
"import": {
- "label": "チャット履歴、設定、プロンプトをインポートする",
+ "label": "チャット履歴、知識ベース、プロンプトをインポート",
"button": "データをインポート",
"success": "インポート成功",
"error": "インポートエラー"
diff --git a/src/assets/locale/ml/settings.json b/src/assets/locale/ml/settings.json
index 5994d0c..97152cd 100644
--- a/src/assets/locale/ml/settings.json
+++ b/src/assets/locale/ml/settings.json
@@ -44,16 +44,16 @@
"confirm": "നിങ്ങളുടെ ചാറ്റ് ചരിത്രം ഇല്ലാതാക്കണമെന്ന് ഉറപ്പാണോ? ഈ പ്രവർത്തനം പിന്നീട് പിന്വലിക്കാനാവില്ല."
},
"export": {
- "label": "ചാറ്റ് ചരിത്രം, ക്രമീകരണങ്ങൾ, പ്രോംപ്റ്റുകൾ എക്സ്പോർട്ട് ചെയ്യുക",
+ "label": "ചാറ്റ് ചരിത്രം, അറിവ് അടിസ്ഥാനം, പ്രോംപ്റ്റുകൾ എക്സ്പോർട്ട് ചെയ്യുക",
"button": "ഡാറ്റ എക്സ്പോർട്ട് ചെയ്യുക",
"success": "എക്സ്പോർട്ട് വിജയകരമായി"
- },
- "import": {
- "label": "ചാറ്റ് ചരിത്രം, ക്രമീകരണങ്ങൾ, പ്രോംപ്റ്റുകൾ ഇമ്പോർട്ട് ചെയ്യുക",
+ },
+ "import": {
+ "label": "ചാറ്റ് ചരിത്രം, അറിവ് അടിസ്ഥാനം, പ്രോംപ്റ്റുകൾ ഇമ്പോർട്ട് ചെയ്യുക",
"button": "ഡാറ്റ ഇമ്പോർട്ട് ചെയ്യുക",
"success": "ഇമ്പോർട്ട് വിജയകരമായി",
- "error": "ഇമ്പോർട്ട് പരാജയപ്പെട്ടു"
- }
+ "error": "ഇമ്പോർട്ട് പിശക്"
+ }
},
"tts": {
"heading": "ടെക്സ്റ്റ്-ടു-സ്പീച്ച് ക്രമീകരണങ്ങൾ",
diff --git a/src/assets/locale/ru/settings.json b/src/assets/locale/ru/settings.json
index dee3775..c48c357 100644
--- a/src/assets/locale/ru/settings.json
+++ b/src/assets/locale/ru/settings.json
@@ -41,13 +41,13 @@
"confirm": "Вы уверены, что хотите удалить историю чата? Это действие нельзя отменить."
},
"export": {
- "label": "Экспорт истории чата, настроек и подсказок",
- "button": "Экспорт данных",
+ "label": "Экспорт истории чата, базы знаний и подсказок",
+ "button": "Экспортировать данные",
"success": "Экспорт успешен"
},
"import": {
- "label": "Импорт истории чата, настроек и подсказок",
- "button": "Импорт данных",
+ "label": "Импорт истории чата, базы знаний и подсказок",
+ "button": "Импортировать данные",
"success": "Импорт успешен",
"error": "Ошибка импорта"
}
diff --git a/src/assets/locale/zh/settings.json b/src/assets/locale/zh/settings.json
index 444814f..70b8d3c 100644
--- a/src/assets/locale/zh/settings.json
+++ b/src/assets/locale/zh/settings.json
@@ -44,12 +44,12 @@
"confirm": "您确定要删除聊天记录吗?此操作无法撤销。"
},
"export": {
- "label": "导出聊天记录、设置和提示",
+ "label": "导出聊天记录、知识库和提示",
"button": "导出数据",
"success": "导出成功"
},
"import": {
- "label": "导入聊天记录、设置和提示",
+ "label": "导入聊天记录、知识库和提示",
"button": "导入数据",
"success": "导入成功",
"error": "导入错误"
diff --git a/src/components/Common/Beta.tsx b/src/components/Common/Beta.tsx
new file mode 100644
index 0000000..c381ae3
--- /dev/null
+++ b/src/components/Common/Beta.tsx
@@ -0,0 +1,8 @@
+import { Tag } from "antd"
+import { useTranslation } from "react-i18next"
+
+export const BetaTag = () => {
+ const { t } = useTranslation("common")
+
+ return {t("beta")}
+}
diff --git a/src/components/Common/ModelSelect.tsx b/src/components/Common/ModelSelect.tsx
new file mode 100644
index 0000000..22160b8
--- /dev/null
+++ b/src/components/Common/ModelSelect.tsx
@@ -0,0 +1,63 @@
+import { useQuery } from "@tanstack/react-query"
+import { Dropdown, Tooltip } from "antd"
+import { LucideBrain } from "lucide-react"
+import React from "react"
+import { useTranslation } from "react-i18next"
+import { OllamaIcon } from "../Icons/Ollama"
+import { fetchChatModels } from "@/services/ollama"
+import { useMessage } from "@/hooks/useMessage"
+
+export const ModelSelect: React.FC = () => {
+ const { t } = useTranslation("common")
+ const { setSelectedModel, selectedModel } = useMessage()
+ const { data } = useQuery({
+ queryKey: ["getAllModelsForSelect"],
+ queryFn: async () => {
+ const models = await fetchChatModels({ returnEmpty: false })
+ return models
+ }
+ })
+
+ return (
+ <>
+ {data && data.length > 0 && (
+ ({
+ key: d.name,
+ label: (
+
+ ),
+ onClick: () => {
+ if (selectedModel === d.name) {
+ setSelectedModel(null)
+ } else {
+ setSelectedModel(d.name)
+ }
+ }
+ })) || [],
+ style: {
+ maxHeight: 500,
+ overflowY: "scroll"
+ },
+ className: "no-scrollbar",
+ activeKey: selectedModel
+ }}
+ placement={"topLeft"}
+ trigger={["click"]}>
+
+
+
+
+ )}
+ >
+ )
+}
diff --git a/src/components/Layouts/Layout.tsx b/src/components/Layouts/Layout.tsx
index 296c641..03916be 100644
--- a/src/components/Layouts/Layout.tsx
+++ b/src/components/Layouts/Layout.tsx
@@ -63,13 +63,18 @@ export default function OptionLayout({
return prompts?.find((prompt) => prompt.id === id)
}
- const handlePromptChange = (value: string) => {
+ const handlePromptChange = (value?: string) => {
+ if (!value) {
+ setSelectedSystemPrompt(undefined)
+ setSelectedQuickPrompt(undefined)
+ return
+ }
const prompt = getPromptInfoById(value)
if (prompt?.is_system) {
setSelectedSystemPrompt(prompt.id)
} else {
+ setSelectedSystemPrompt(undefined)
setSelectedQuickPrompt(prompt!.content)
- setSelectedSystemPrompt("")
}
}
diff --git a/src/components/Layouts/SettingsOptionLayout.tsx b/src/components/Layouts/SettingsOptionLayout.tsx
index 051fdbb..fa074cf 100644
--- a/src/components/Layouts/SettingsOptionLayout.tsx
+++ b/src/components/Layouts/SettingsOptionLayout.tsx
@@ -10,6 +10,7 @@ import { useTranslation } from "react-i18next"
import { Link, useLocation } from "react-router-dom"
import { OllamaIcon } from "../Icons/Ollama"
import { Tag } from "antd"
+import { BetaTag } from "../Common/Beta"
function classNames(...classes: string[]) {
return classes.filter(Boolean).join(" ")
@@ -81,7 +82,7 @@ export const SettingsLayout = ({ children }: { children: React.ReactNode }) => {
name={
{t("manageKnowledge.title")}
- {t("common:beta")}
+
}
icon={BlocksIcon}
diff --git a/src/components/Option/Settings/other.tsx b/src/components/Option/Settings/other.tsx
index 65383f0..e33b389 100644
--- a/src/components/Option/Settings/other.tsx
+++ b/src/components/Option/Settings/other.tsx
@@ -9,6 +9,11 @@ import { SearchModeSettings } from "./search-mode"
import { useTranslation } from "react-i18next"
import { useI18n } from "@/hooks/useI18n"
import { TTSModeSettings } from "./tts-mode"
+import {
+ exportPageAssistData,
+ importPageAssistData
+} from "@/libs/export-import"
+import { BetaTag } from "@/components/Common/Beta"
export const SettingOther = () => {
const { clearChat, speechToTextLanguage, setSpeechToTextLanguage } =
@@ -90,7 +95,7 @@ export const SettingOther = () => {
-
+
@@ -98,7 +103,7 @@ export const SettingOther = () => {
-
+
{t("generalSettings.system.deleteChatHistory.label")}
@@ -122,6 +127,37 @@ export const SettingOther = () => {
{t("generalSettings.system.deleteChatHistory.button")}
+
+
+ {t("generalSettings.system.export.label")}
+
+
+
+
+
+ {t("generalSettings.system.import.label")}
+
+
+ {
+ if (e.target.files) {
+ importPageAssistData(e.target.files[0])
+ }
+ }}
+ />
+
)
diff --git a/src/components/Sidepanel/Chat/empty.tsx b/src/components/Sidepanel/Chat/empty.tsx
index 41305b8..499e320 100644
--- a/src/components/Sidepanel/Chat/empty.tsx
+++ b/src/components/Sidepanel/Chat/empty.tsx
@@ -1,4 +1,4 @@
-import { useQuery } from "@tanstack/react-query"
+import { useQuery, useQueryClient } from "@tanstack/react-query"
import { Select } from "antd"
import { RotateCcw } from "lucide-react"
import { useEffect, useState } from "react"
@@ -15,6 +15,7 @@ import {
export const EmptySidePanel = () => {
const [ollamaURL, setOllamaURL] = useState
("")
const { t } = useTranslation(["playground", "common"])
+ const queryClient = useQueryClient()
const {
data: ollamaInfo,
status: ollamaStatus,
@@ -26,7 +27,9 @@ export const EmptySidePanel = () => {
const ollamaURL = await getOllamaURL()
const isOk = await isOllamaRunning()
const models = await fetchChatModels({ returnEmpty: false })
-
+ queryClient.invalidateQueries({
+ queryKey: ["getAllModelsForSelect"]
+ })
return {
isOk,
models,
diff --git a/src/components/Sidepanel/Chat/form.tsx b/src/components/Sidepanel/Chat/form.tsx
index b8b3fc9..45ec340 100644
--- a/src/components/Sidepanel/Chat/form.tsx
+++ b/src/components/Sidepanel/Chat/form.tsx
@@ -10,6 +10,7 @@ import { useWebUI } from "~/store/webui"
import { defaultEmbeddingModelForRag } from "~/services/ollama"
import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react"
import { useTranslation } from "react-i18next"
+import { ModelSelect } from "@/components/Common/ModelSelect"
type Props = {
dropedFile: File | undefined
@@ -186,6 +187,7 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
{...form.getInputProps("message")}
/>
+