From 2b087861497e7707d3b3ea0261fe6b0fdcb63001 Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Fri, 13 Dec 2024 18:08:19 +0530 Subject: [PATCH 1/9] fix: update setLastUsedChatSystemPrompt calls to use newHistoryId.id --- src/hooks/chat-helper/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/chat-helper/index.ts b/src/hooks/chat-helper/index.ts index 0fe65c4..3404c81 100644 --- a/src/hooks/chat-helper/index.ts +++ b/src/hooks/chat-helper/index.ts @@ -108,7 +108,7 @@ export const saveMessageOnError = async ({ setHistoryId(newHistoryId.id) await setLastUsedChatModel(newHistoryId.id, selectedModel) if (prompt_id || prompt_content) { - await setLastUsedChatSystemPrompt(historyId, { prompt_content, prompt_id }) + await setLastUsedChatSystemPrompt(newHistoryId.id, { prompt_content, prompt_id }) } } @@ -203,7 +203,7 @@ export const saveMessageOnSuccess = async ({ setHistoryId(newHistoryId.id) await setLastUsedChatModel(newHistoryId.id, selectedModel!) if (prompt_id || prompt_content) { - await setLastUsedChatSystemPrompt(historyId, { prompt_content, prompt_id }) + await setLastUsedChatSystemPrompt(newHistoryId.id, { prompt_content, prompt_id }) } } } From 143541e915fd341f89c249beec0d3a72a48fa539 Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Fri, 13 Dec 2024 18:08:31 +0530 Subject: [PATCH 2/9] chore: bump version to 1.3.8 --- wxt.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wxt.config.ts b/wxt.config.ts index 06bd4b4..d4b1fe4 100644 --- a/wxt.config.ts +++ b/wxt.config.ts @@ -50,7 +50,7 @@ export default defineConfig({ outDir: "build", manifest: { - version: "1.3.7", + version: "1.3.8", name: process.env.TARGET === "firefox" ? "Page Assist - A Web UI for Local AI Models" From caf1dfcbe80afed8af16dd7f262a64fbdeb3ecea Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Fri, 13 Dec 2024 18:25:05 +0530 Subject: [PATCH 3/9] feat: Clear all browser storage when deleting chat history and use local instead of sync --- src/components/Option/Settings/general-settings.tsx | 7 +++++++ src/services/model-settings.ts | 9 +++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/Option/Settings/general-settings.tsx b/src/components/Option/Settings/general-settings.tsx index c471fd4..aca0cb3 100644 --- a/src/components/Option/Settings/general-settings.tsx +++ b/src/components/Option/Settings/general-settings.tsx @@ -239,6 +239,13 @@ export const GeneralSettings = () => { }) clearChat() } + try { + await browser.storage.sync.clear() + await browser.storage.local.clear() + await browser.storage.session.clear() + } catch (e) { + console.log("Error clearing storage:", e) + } }} className="bg-red-500 dark:bg-red-600 text-white dark:text-gray-200 px-4 py-2 rounded-md"> {t("generalSettings.system.deleteChatHistory.button")} diff --git a/src/services/model-settings.ts b/src/services/model-settings.ts index 6e96c58..1993442 100644 --- a/src/services/model-settings.ts +++ b/src/services/model-settings.ts @@ -1,5 +1,7 @@ import { Storage } from "@plasmohq/storage" -const storage = new Storage() +const storage = new Storage({ + area: "local" +}) type ModelSettings = { f16KV?: boolean @@ -63,7 +65,7 @@ const keys = [ "vocabOnly" ] -const getAllModelSettings = async () => { +export const getAllModelSettings = async () => { try { const settings: ModelSettings = {} for (const key of keys) { @@ -80,7 +82,7 @@ const getAllModelSettings = async () => { } } -const setModelSetting = async ( +export const setModelSetting = async ( key: string, value: string | number | boolean ) => { @@ -144,4 +146,3 @@ export const setLastUsedChatSystemPrompt = async ( await storage.set(`lastUsedChatSystemPrompt-${historyId}`, prompt) } -export { getAllModelSettings, setModelSetting } From 44e2057ff44dc34c44fb10de9c12eaf75e7f5644 Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Fri, 13 Dec 2024 18:32:50 +0530 Subject: [PATCH 4/9] feat: Update system reset functionality in settings --- src/assets/locale/da/settings.json | 6 +- src/assets/locale/de/settings.json | 9 ++- src/assets/locale/en/settings.json | 6 +- src/assets/locale/es/settings.json | 6 +- src/assets/locale/fa/settings.json | 6 +- src/assets/locale/fr/settings.json | 6 +- src/assets/locale/it/settings.json | 6 +- src/assets/locale/ja-JP/settings.json | 6 +- src/assets/locale/ko/settings.json | 6 +- src/assets/locale/ml/settings.json | 6 +- src/assets/locale/no/settings.json | 6 +- src/assets/locale/pt-BR/settings.json | 6 +- src/assets/locale/ru/settings.json | 6 +- src/assets/locale/sv/settings.json | 6 +- src/assets/locale/uk/settings.json | 6 +- src/assets/locale/zh/settings.json | 6 +- .../Option/Settings/general-settings.tsx | 64 ++++++++++--------- 17 files changed, 82 insertions(+), 81 deletions(-) diff --git a/src/assets/locale/da/settings.json b/src/assets/locale/da/settings.json index 37168c4..b612c68 100644 --- a/src/assets/locale/da/settings.json +++ b/src/assets/locale/da/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Systemindstillinger", "deleteChatHistory": { - "label": "Slet Chathistorik", - "button": "Slet", - "confirm": "Er du sikker på, at du vil slette din chathistorik? Denne handling kan ikke fortrydes." + "label": "System Nulstilling", + "button": "Nulstil Alt", + "confirm": "Er du sikker på, at du vil udføre en systemnulstilling? Dette vil slette alle data og kan ikke fortrydes." }, "export": { "label": "Eksporter chathistorik, vidensbase og prompts", diff --git a/src/assets/locale/de/settings.json b/src/assets/locale/de/settings.json index 6315f85..0e2ac78 100644 --- a/src/assets/locale/de/settings.json +++ b/src/assets/locale/de/settings.json @@ -75,11 +75,10 @@ "system": { "heading": "Systemeinstellungen", "deleteChatHistory": { - "label": "Chatverlauf löschen", - "button": "Löschen", - "confirm": "Sind Sie sicher, dass Sie Ihren Chatverlauf löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden." - }, - "export": { + "label": "System zurücksetzen", + "button": "Alles zurücksetzen", + "confirm": "Sind Sie sicher, dass Sie einen Systemreset durchführen möchten? Dies löscht alle Daten und kann nicht rückgängig gemacht werden." + }, "export": { "label": "Chatverlauf, Wissensbasis und Prompts exportieren", "button": "Daten exportieren", "success": "Export erfolgreich" diff --git a/src/assets/locale/en/settings.json b/src/assets/locale/en/settings.json index f0498df..f48b46b 100644 --- a/src/assets/locale/en/settings.json +++ b/src/assets/locale/en/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "System Settings", "deleteChatHistory": { - "label": "Delete Chat History", - "button": "Delete", - "confirm": "Are you sure you want to delete your chat history? This action cannot be undone." + "label": "System Reset", + "button": "Reset All", + "confirm": "Are you sure you want to perform a system reset? This will clear all data and cannot be undone." }, "export": { "label": "Export Chat History, Knowledge Base, and Prompts", diff --git a/src/assets/locale/es/settings.json b/src/assets/locale/es/settings.json index eb98d80..b225c54 100644 --- a/src/assets/locale/es/settings.json +++ b/src/assets/locale/es/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Configuraciones del Sistema", "deleteChatHistory": { - "label": "Borrar Histórico del Chat", - "button": "Borrar", - "confirm": "¿Esta seguro que desea borrar su histórico del chat? Esta acción no podra ser desecha." + "label": "Reinicio del Sistema", + "button": "Reiniciar Todo", + "confirm": "¿Está seguro de que desea realizar un reinicio del sistema? Esto borrará todos los datos y no se puede deshacer." }, "export": { "label": "Exportar Histórico del Chat, Base de Conocimiento y Prompts", diff --git a/src/assets/locale/fa/settings.json b/src/assets/locale/fa/settings.json index 985639a..26be070 100644 --- a/src/assets/locale/fa/settings.json +++ b/src/assets/locale/fa/settings.json @@ -72,9 +72,9 @@ "system": { "heading": "تنظیمات سیستم", "deleteChatHistory": { - "label": "حذف تاریخچه گفتگو", - "button": "حذف", - "confirm": "آیا مطمئن هستید که می خواهید تاریخچه گفتگوهای خود را حذف کنید؟ این عمل قابل برگشت نیست." + "label": "بازنشانی سیستم", + "button": "بازنشانی همه", + "confirm": "آیا مطمئن هستید که می‌خواهید بازنشانی سیستم را انجام دهید؟ این کار تمام داده‌ها را پاک می‌کند و غیرقابل برگشت است." }, "export": { "label": "تاریخچه گپ، پایگاه دانش و پرامپت‌ها را اکسپورت کنید", diff --git a/src/assets/locale/fr/settings.json b/src/assets/locale/fr/settings.json index 3ef9b49..97dec81 100644 --- a/src/assets/locale/fr/settings.json +++ b/src/assets/locale/fr/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Les paramètres du système", "deleteChatHistory": { - "label": "Supprimer l'historique du chat", - "button": "Supprimer", - "confirm": "Êtes-vous sûr de vouloir supprimer l'historique de votre chat? Cette action ne peut pas être annulée." + "label": "Réinitialisation du système", + "button": "Tout réinitialiser", + "confirm": "Êtes-vous sûr de vouloir effectuer une réinitialisation du système ? Cela effacera toutes les données et ne pourra pas être annulé." }, "export": { "label": "Exporter l'historique du chat, la base de connaissances et les invites", diff --git a/src/assets/locale/it/settings.json b/src/assets/locale/it/settings.json index 4e07754..4aa58b9 100644 --- a/src/assets/locale/it/settings.json +++ b/src/assets/locale/it/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Impostazioni di Sistema", "deleteChatHistory": { - "label": "Elimina cronologia Chat", - "button": "Elimina", - "confirm": "Sei sicuro che vuoi eliminare la tua cronologia delle chat? Questa azione non può essere annullata." + "label": "Reset del Sistema", + "button": "Reset Totale", + "confirm": "Sei sicuro di voler eseguire un reset del sistema? Questa operazione cancellerà tutti i dati e non può essere annullata." }, "export": { "label": "Esporta la cronologia Chat, Base di Conoscenza, e Prompts", diff --git a/src/assets/locale/ja-JP/settings.json b/src/assets/locale/ja-JP/settings.json index d34b63b..533aa1e 100644 --- a/src/assets/locale/ja-JP/settings.json +++ b/src/assets/locale/ja-JP/settings.json @@ -78,9 +78,9 @@ "system": { "heading": "システム設定", "deleteChatHistory": { - "label": "チャット履歴を削除する", - "button": "削除", - "confirm": "チャット履歴を削除してもよろしいですか?この操作は元に戻せません。" + "label": "システムリセット", + "button": "すべてリセット", + "confirm": "システムリセットを実行してもよろしいですか?すべてのデータが消去され、元に戻すことはできません。" }, "export": { "label": "チャット履歴、知識ベース、プロンプトをエクスポート", diff --git a/src/assets/locale/ko/settings.json b/src/assets/locale/ko/settings.json index 73ac857..fe31b5f 100644 --- a/src/assets/locale/ko/settings.json +++ b/src/assets/locale/ko/settings.json @@ -78,9 +78,9 @@ "system": { "heading": "시스템 설정", "deleteChatHistory": { - "label": "채팅 기록 삭제", - "button": "삭제", - "confirm": "채팅 기록을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다." + "label": "시스템 초기화", + "button": "전체 초기화", + "confirm": "시스템을 초기화하시겠습니까? 모든 데이터가 삭제되며 되돌릴 수 없습니다." }, "export": { "label": "채팅 기록, 지식 베이스, 프롬프트 내보내기", diff --git a/src/assets/locale/ml/settings.json b/src/assets/locale/ml/settings.json index b9ccb0d..640fc4c 100644 --- a/src/assets/locale/ml/settings.json +++ b/src/assets/locale/ml/settings.json @@ -78,9 +78,9 @@ "system": { "heading": "സിസ്റ്റം ക്രമീകരണങ്ങൾ", "deleteChatHistory": { - "label": "ചാറ്റ് ചരിത്രം ഇല്ലാതാക്കുക", - "button": "ഇല്ലാതാക്കുക", - "confirm": "നിങ്ങളുടെ ചാറ്റ് ചരിത്രം ഇല്ലാതാക്കണമെന്ന് ഉറപ്പാണോ? ഈ പ്രവർത്തനം പിന്നീട് പിന്വലിക്കാനാവില്ല." + "label": "സിസ്റ്റം റീസെറ്റ്", + "button": "എല്ലാം റീസെറ്റ് ചെയ്യുക", + "confirm": "നിങ്ങൾക്ക് സിസ്റ്റം റീസെറ്റ് നടത്താൻ തീർച്ചയാണോ? ഇത് എല്ലാ ഡാറ്റയും മായ്ക്കും, പിന്നീട് പുനഃസ്ഥാപിക്കാൻ കഴിയില്ല." }, "export": { "label": "ചാറ്റ് ചരിത്രം, അറിവ് അടിസ്ഥാനം, പ്രോംപ്റ്റുകൾ എക്സ്പോർട്ട് ചെയ്യുക", diff --git a/src/assets/locale/no/settings.json b/src/assets/locale/no/settings.json index c73cbec..1b994a8 100644 --- a/src/assets/locale/no/settings.json +++ b/src/assets/locale/no/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Systeminnstillinger", "deleteChatHistory": { - "label": "Slett Chathistorikk", - "button": "Slett", - "confirm": "Er du sikker på at du vil slette chathistorikken din? Denne handlingen kan ikke angres." + "label": "System Tilbakestilling", + "button": "Tilbakestill Alt", + "confirm": "Er du sikker på at du vil utføre en system tilbakestilling? Dette vil slette alle data og kan ikke angres." }, "export": { "label": "Eksporter chathistorikk, kunnskapsbase og prompts", diff --git a/src/assets/locale/pt-BR/settings.json b/src/assets/locale/pt-BR/settings.json index 019ad68..e7adfb7 100644 --- a/src/assets/locale/pt-BR/settings.json +++ b/src/assets/locale/pt-BR/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Configurações do Sistema", "deleteChatHistory": { - "label": "Excluir Histórico de Chat", - "button": "Excluir", - "confirm": "Tem certeza de que deseja excluir seu histórico de chat? Esta ação não pode ser desfeita." + "label": "Reiniciar Sistema", + "button": "Reiniciar Tudo", + "confirm": "Tem certeza que deseja realizar um reinício do sistema? Isso irá apagar todos os dados e não poderá ser desfeito." }, "export": { "label": "Exportar Histórico de Chat, Base de Conhecimento e Prompts", diff --git a/src/assets/locale/ru/settings.json b/src/assets/locale/ru/settings.json index 7e6b75b..710ffdc 100644 --- a/src/assets/locale/ru/settings.json +++ b/src/assets/locale/ru/settings.json @@ -76,9 +76,9 @@ "system": { "heading": "Настройки системы", "deleteChatHistory": { - "label": "Удалить историю чата", - "button": "Удалить", - "confirm": "Вы уверены, что хотите удалить историю чата? Это действие нельзя отменить." + "label": "Сброс системы", + "button": "Сбросить все", + "confirm": "Вы уверены, что хотите выполнить сброс системы? Это удалит все данные без возможности восстановления." }, "export": { "label": "Экспорт истории чата, базы знаний и подсказок", diff --git a/src/assets/locale/sv/settings.json b/src/assets/locale/sv/settings.json index 3edaa52..7ed494a 100644 --- a/src/assets/locale/sv/settings.json +++ b/src/assets/locale/sv/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Systeminställningar", "deleteChatHistory": { - "label": "Radera Chatt Historik", - "button": "Radera", - "confirm": "Är du säker på att du vill radera din chatthistorik? Denna åtgärd kan inte ångras." + "label": "Systemåterställning", + "button": "Återställ Allt", + "confirm": "Är du säker på att du vill utföra en systemåterställning? Detta kommer att radera all data och kan inte ångras." }, "export": { "label": "Exportera chatthistorik, kunskapsbas och instruktioner", diff --git a/src/assets/locale/uk/settings.json b/src/assets/locale/uk/settings.json index 91fe5de..f1526c3 100644 --- a/src/assets/locale/uk/settings.json +++ b/src/assets/locale/uk/settings.json @@ -75,9 +75,9 @@ "system": { "heading": "Системні налаштування", "deleteChatHistory": { - "label": "Видалити історію чату", - "button": "Видалити", - "confirm": "Ви впевнені, що хочете видалити історію чату? Ця дія не може бути відвернута." + "label": "Скидання системи", + "button": "Скинути все", + "confirm": "Ви впевнені, що хочете виконати скидання системи? Це призведе до видалення всіх даних, і цю дію неможливо буде скасувати." }, "export": { "label": "Експорт історії чату, бази знань та запитів", diff --git a/src/assets/locale/zh/settings.json b/src/assets/locale/zh/settings.json index 83c576d..24fa548 100644 --- a/src/assets/locale/zh/settings.json +++ b/src/assets/locale/zh/settings.json @@ -78,9 +78,9 @@ "system": { "heading": "系统设置", "deleteChatHistory": { - "label": "删除聊天记录", - "button": "删除", - "confirm": "您确定要删除聊天记录吗?此操作无法撤销。" + "label": "系统重置", + "button": "全部重置", + "confirm": "您确定要执行系统重置吗?这将清除所有数据且无法撤消。" }, "export": { "label": "导出聊天记录、知识库和提示", diff --git a/src/components/Option/Settings/general-settings.tsx b/src/components/Option/Settings/general-settings.tsx index aca0cb3..e5b6d35 100644 --- a/src/components/Option/Settings/general-settings.tsx +++ b/src/components/Option/Settings/general-settings.tsx @@ -220,37 +220,7 @@ export const GeneralSettings = () => {
-
- - {t("generalSettings.system.deleteChatHistory.label")} - - - -
+
{t("generalSettings.system.export.label")} @@ -282,6 +252,38 @@ export const GeneralSettings = () => { }} />
+ +
+ + {t("generalSettings.system.deleteChatHistory.label")} + + + +
) From fd6eea3e8489feab8a72e41401170d351c77f204 Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Fri, 13 Dec 2024 20:03:52 +0530 Subject: [PATCH 5/9] feat: Add Brave Search API support --- src/assets/locale/da/settings.json | 4 + src/assets/locale/de/settings.json | 7 +- src/assets/locale/en/settings.json | 4 + src/assets/locale/es/settings.json | 4 + src/assets/locale/fa/settings.json | 4 + src/assets/locale/fr/settings.json | 4 + src/assets/locale/it/settings.json | 4 + src/assets/locale/ja-JP/settings.json | 4 + src/assets/locale/ko/settings.json | 4 + src/assets/locale/ml/settings.json | 4 + src/assets/locale/no/settings.json | 4 + src/assets/locale/pt-BR/settings.json | 4 + src/assets/locale/ru/settings.json | 4 + src/assets/locale/sv/settings.json | 4 + src/assets/locale/uk/settings.json | 4 + src/assets/locale/zh/settings.json | 4 + .../Option/Playground/PlaygroundChat.tsx | 2 +- .../Option/Settings/search-mode.tsx | 24 +++- src/services/search.ts | 30 +++- src/utils/search-provider.ts | 4 + src/web/search-engines/brave-api.ts | 128 ++++++++++++++++++ src/web/web.ts | 3 + 22 files changed, 248 insertions(+), 10 deletions(-) create mode 100644 src/web/search-engines/brave-api.ts diff --git a/src/assets/locale/da/settings.json b/src/assets/locale/da/settings.json index b612c68..1712a45 100644 --- a/src/assets/locale/da/settings.json +++ b/src/assets/locale/da/settings.json @@ -70,6 +70,10 @@ "url": { "label": "SearXNG URL" } + }, + "braveApi": { + "label": "Brave API Nøgle", + "placeholder": "Indtast din Brave API nøgle" } }, "system": { diff --git a/src/assets/locale/de/settings.json b/src/assets/locale/de/settings.json index 0e2ac78..581cc28 100644 --- a/src/assets/locale/de/settings.json +++ b/src/assets/locale/de/settings.json @@ -70,6 +70,10 @@ "url": { "label": "SearXNG-URL" } + }, + "braveApi": { + "label": "Brave API-Schlüssel", + "placeholder": "Geben Sie Ihren Brave API-Schlüssel ein" } }, "system": { @@ -78,7 +82,8 @@ "label": "System zurücksetzen", "button": "Alles zurücksetzen", "confirm": "Sind Sie sicher, dass Sie einen Systemreset durchführen möchten? Dies löscht alle Daten und kann nicht rückgängig gemacht werden." - }, "export": { + }, + "export": { "label": "Chatverlauf, Wissensbasis und Prompts exportieren", "button": "Daten exportieren", "success": "Export erfolgreich" diff --git a/src/assets/locale/en/settings.json b/src/assets/locale/en/settings.json index f48b46b..d32dccf 100644 --- a/src/assets/locale/en/settings.json +++ b/src/assets/locale/en/settings.json @@ -70,6 +70,10 @@ "url": { "label": "SearXNG URL" } + }, + "braveApi": { + "label": "Brave API Key", + "placeholder": "Enter your Brave API key" } }, "system": { diff --git a/src/assets/locale/es/settings.json b/src/assets/locale/es/settings.json index b225c54..3809ff1 100644 --- a/src/assets/locale/es/settings.json +++ b/src/assets/locale/es/settings.json @@ -70,6 +70,10 @@ "url": { "label": "URL de SearXNG" } + }, + "braveApi": { + "label": "Clave API de Brave", + "placeholder": "Ingrese su clave API de Brave" } }, "system": { diff --git a/src/assets/locale/fa/settings.json b/src/assets/locale/fa/settings.json index 26be070..bb037ff 100644 --- a/src/assets/locale/fa/settings.json +++ b/src/assets/locale/fa/settings.json @@ -67,6 +67,10 @@ "url": { "label": "آدرس SearXNG" } + }, + "braveApi": { + "label": "کلید API بریو", + "placeholder": "کلید API بریو خود را وارد کنید" } }, "system": { diff --git a/src/assets/locale/fr/settings.json b/src/assets/locale/fr/settings.json index 97dec81..93ba685 100644 --- a/src/assets/locale/fr/settings.json +++ b/src/assets/locale/fr/settings.json @@ -70,6 +70,10 @@ "url": { "label": "URL SearXNG" } + }, + "braveApi": { + "label": "Clé API Brave", + "placeholder": "Entrez votre clé API Brave" } }, "system": { diff --git a/src/assets/locale/it/settings.json b/src/assets/locale/it/settings.json index 4aa58b9..d7d7007 100644 --- a/src/assets/locale/it/settings.json +++ b/src/assets/locale/it/settings.json @@ -70,6 +70,10 @@ "url": { "label": "URL SearXNG" } + }, + "braveApi": { + "label": "Chiave API Brave", + "placeholder": "Inserisci la tua chiave API Brave" } }, "system": { diff --git a/src/assets/locale/ja-JP/settings.json b/src/assets/locale/ja-JP/settings.json index 533aa1e..62363a5 100644 --- a/src/assets/locale/ja-JP/settings.json +++ b/src/assets/locale/ja-JP/settings.json @@ -73,6 +73,10 @@ "url": { "label": "SearXNG URL" } + }, + "braveApi": { + "label": "Brave APIキー", + "placeholder": "Brave APIキーを入力してください" } }, "system": { diff --git a/src/assets/locale/ko/settings.json b/src/assets/locale/ko/settings.json index fe31b5f..f4f019a 100644 --- a/src/assets/locale/ko/settings.json +++ b/src/assets/locale/ko/settings.json @@ -73,6 +73,10 @@ "url": { "label": "SearXNG URL" } + }, + "braveApi": { + "label": "Brave API 키", + "placeholder": "Brave API 키를 입력하세요" } }, "system": { diff --git a/src/assets/locale/ml/settings.json b/src/assets/locale/ml/settings.json index 640fc4c..e18ef5e 100644 --- a/src/assets/locale/ml/settings.json +++ b/src/assets/locale/ml/settings.json @@ -73,6 +73,10 @@ "url": { "label": "SearXNG URL" } + }, + "braveApi": { + "label": "ബ്രേവ് API കീ", + "placeholder": "നിങ്ങളുടെ ബ്രേവ് API കീ നൽകുക" } }, "system": { diff --git a/src/assets/locale/no/settings.json b/src/assets/locale/no/settings.json index 1b994a8..cd96712 100644 --- a/src/assets/locale/no/settings.json +++ b/src/assets/locale/no/settings.json @@ -70,6 +70,10 @@ "url": { "label": "SearXNG URL" } + }, + "braveApi": { + "label": "Brave API Nøkkel", + "placeholder": "Skriv inn din Brave API nøkkel" } }, "system": { diff --git a/src/assets/locale/pt-BR/settings.json b/src/assets/locale/pt-BR/settings.json index e7adfb7..6dbd407 100644 --- a/src/assets/locale/pt-BR/settings.json +++ b/src/assets/locale/pt-BR/settings.json @@ -70,6 +70,10 @@ "url": { "label": "URL do SearXNG" } + }, + "braveApi": { + "label": "Chave da API do Brave", + "placeholder": "Digite sua chave da API do Brave" } }, "system": { diff --git a/src/assets/locale/ru/settings.json b/src/assets/locale/ru/settings.json index 710ffdc..c71c037 100644 --- a/src/assets/locale/ru/settings.json +++ b/src/assets/locale/ru/settings.json @@ -71,6 +71,10 @@ "url": { "label": "URL-адрес SearXNG" } + }, + "braveApi": { + "label": "API-ключ Brave", + "placeholder": "Введите ваш API-ключ Brave" } }, "system": { diff --git a/src/assets/locale/sv/settings.json b/src/assets/locale/sv/settings.json index 7ed494a..712e9a3 100644 --- a/src/assets/locale/sv/settings.json +++ b/src/assets/locale/sv/settings.json @@ -70,6 +70,10 @@ "url": { "label": "SearXNG URL" } + }, + "braveApi": { + "label": "Brave API-nyckel", + "placeholder": "Ange din Brave API-nyckel" } }, "system": { diff --git a/src/assets/locale/uk/settings.json b/src/assets/locale/uk/settings.json index f1526c3..7462317 100644 --- a/src/assets/locale/uk/settings.json +++ b/src/assets/locale/uk/settings.json @@ -70,6 +70,10 @@ "url": { "label": "SearXNG URL-адреса" } + }, + "braveApi": { + "label": "Ключ API Brave", + "placeholder": "Введіть ваш ключ API Brave" } }, "system": { diff --git a/src/assets/locale/zh/settings.json b/src/assets/locale/zh/settings.json index 24fa548..2557c44 100644 --- a/src/assets/locale/zh/settings.json +++ b/src/assets/locale/zh/settings.json @@ -73,6 +73,10 @@ "url": { "label": "SearXNG 网址" } + }, + "braveApi": { + "label": "Brave API 密钥", + "placeholder": "输入您的 Brave API 密钥" } }, "system": { diff --git a/src/components/Option/Playground/PlaygroundChat.tsx b/src/components/Option/Playground/PlaygroundChat.tsx index aaf3462..ea5361f 100644 --- a/src/components/Option/Playground/PlaygroundChat.tsx +++ b/src/components/Option/Playground/PlaygroundChat.tsx @@ -27,7 +27,7 @@ export const PlaygroundChat = () => { <>
+ className="custom-scrollbar grow flex flex-col md:translate-x-0 transition-transform duration-300 ease-in-out overflow-y-auto h-[calc(100vh-160px)]"> {messages.length === 0 && (
diff --git a/src/components/Option/Settings/search-mode.tsx b/src/components/Option/Settings/search-mode.tsx index 69ae112..932632b 100644 --- a/src/components/Option/Settings/search-mode.tsx +++ b/src/components/Option/Settings/search-mode.tsx @@ -2,7 +2,7 @@ import { SaveButton } from "@/components/Common/SaveButton" import { getSearchSettings, setSearchSettings } from "@/services/search" import { SUPPORTED_SERACH_PROVIDERS } from "@/utils/search-provider" import { useForm } from "@mantine/form" -import { useQuery, useQueryClient } from "@tanstack/react-query" +import { useQuery } from "@tanstack/react-query" import { Select, Skeleton, Switch, InputNumber, Input } from "antd" import { useTranslation } from "react-i18next" @@ -16,7 +16,8 @@ export const SearchModeSettings = () => { totalSearchResults: 0, visitSpecificWebsite: false, searxngURL: "", - searxngJSONMode: false + searxngJSONMode: false, + braveApiKey: "", } }) @@ -81,6 +82,25 @@ export const SearchModeSettings = () => {
)} + {form.values.searchProvider === "brave-api" && ( + <> +
+ + {t("generalSettings.webSearch.braveApi.label")} + +
+ +
+
+ + )}
{t("generalSettings.webSearch.searchMode.label")} diff --git a/src/services/search.ts b/src/services/search.ts index 66fb5cf..73b3327 100644 --- a/src/services/search.ts +++ b/src/services/search.ts @@ -1,6 +1,9 @@ import { Storage } from "@plasmohq/storage" const storage = new Storage() +const storage2 = new Storage({ + area: "local" +}) const TOTAL_SEARCH_RESULTS = 2 const DEFAULT_PROVIDER = "google" @@ -80,10 +83,20 @@ export const setSearxngURL = async (searxngURL: string) => { await storage.set("searxngURL", searxngURL) } +export const getBraveApiKey = async () => { + const braveApiKey = await storage2.get("braveApiKey") + return braveApiKey || "" +} + +export const setBraveApiKey = async (braveApiKey: string) => { + await storage2.set("braveApiKey", braveApiKey) +} + export const getSearchSettings = async () => { const [isSimpleInternetSearch, searchProvider, totalSearchResult, visitSpecificWebsite, searxngURL, - searxngJSONMode + searxngJSONMode, + braveApiKey ] = await Promise.all([ getIsSimpleInternetSearch(), @@ -91,7 +104,8 @@ export const getSearchSettings = async () => { totalSearchResults(), getIsVisitSpecificWebsite(), getSearxngURL(), - isSearxngJSONMode() + isSearxngJSONMode(), + getBraveApiKey() ]) return { @@ -100,7 +114,8 @@ export const getSearchSettings = async () => { totalSearchResults: totalSearchResult, visitSpecificWebsite, searxngURL, - searxngJSONMode + searxngJSONMode, + braveApiKey } } @@ -110,14 +125,16 @@ export const setSearchSettings = async ({ totalSearchResults, visitSpecificWebsite, searxngJSONMode, - searxngURL + searxngURL, + braveApiKey }: { isSimpleInternetSearch: boolean searchProvider: string totalSearchResults: number visitSpecificWebsite: boolean searxngURL: string - searxngJSONMode: boolean + searxngJSONMode: boolean, + braveApiKey: string }) => { await Promise.all([ setIsSimpleInternetSearch(isSimpleInternetSearch), @@ -125,6 +142,7 @@ export const setSearchSettings = async ({ setTotalSearchResults(totalSearchResults), setIsVisitSpecificWebsite(visitSpecificWebsite), setSearxngJSONMode(searxngJSONMode), - setSearxngURL(searxngURL) + setSearxngURL(searxngURL), + setBraveApiKey(braveApiKey) ]) } diff --git a/src/utils/search-provider.ts b/src/utils/search-provider.ts index 404c13f..24004a4 100644 --- a/src/utils/search-provider.ts +++ b/src/utils/search-provider.ts @@ -18,5 +18,9 @@ export const SUPPORTED_SERACH_PROVIDERS = [ { label: "Searxng", value: "searxng" + }, + { + label: "Brave Search API", + value: "brave-api" } ] \ No newline at end of file diff --git a/src/web/search-engines/brave-api.ts b/src/web/search-engines/brave-api.ts new file mode 100644 index 0000000..5e13312 --- /dev/null +++ b/src/web/search-engines/brave-api.ts @@ -0,0 +1,128 @@ +import { cleanUrl } from "~/libs/clean-url" +import { getIsSimpleInternetSearch, totalSearchResults, getBraveApiKey } from "@/services/search" +import { pageAssistEmbeddingModel } from "@/models/embedding" +import type { Document } from "@langchain/core/documents" +import { RecursiveCharacterTextSplitter } from "langchain/text_splitter" +import { MemoryVectorStore } from "langchain/vectorstores/memory" +import { PageAssistHtmlLoader } from "~/loader/html" +import { + defaultEmbeddingChunkOverlap, + defaultEmbeddingChunkSize, + defaultEmbeddingModelForRag, + getOllamaURL +} from "~/services/ollama" + +interface BraveAPIResult { + title: string + url: string + description: string +} + +interface BraveAPIResponse { + web: { + results: BraveAPIResult[] + } +} + +export const braveAPISearch = async (query: string) => { + const braveApiKey = await getBraveApiKey() + if (!braveApiKey || braveApiKey.trim() === "") { + throw new Error("Brave API key not configured") + } + const results = await apiBraveSearch(braveApiKey, query) + const TOTAL_SEARCH_RESULTS = await totalSearchResults() + + const searchResults = results.slice(0, TOTAL_SEARCH_RESULTS) + + const isSimpleMode = await getIsSimpleInternetSearch() + + if (isSimpleMode) { + await getOllamaURL() + return searchResults.map((result) => { + return { + url: result.link, + content: result.content + } + }) + } + + const docs: Document>[] = [] + try { + for (const result of searchResults) { + const loader = new PageAssistHtmlLoader({ + html: "", + url: result.link + }) + + const documents = await loader.loadByURL() + documents.forEach((doc) => { + docs.push(doc) + }) + } + } catch (error) { + console.error(error) + } + + const ollamaUrl = await getOllamaURL() + const embeddingModel = await defaultEmbeddingModelForRag() + const ollamaEmbedding = await pageAssistEmbeddingModel({ + model: embeddingModel || "", + baseUrl: cleanUrl(ollamaUrl) + }) + + const chunkSize = await defaultEmbeddingChunkSize() + const chunkOverlap = await defaultEmbeddingChunkOverlap() + const textSplitter = new RecursiveCharacterTextSplitter({ + chunkSize, + chunkOverlap + }) + + const chunks = await textSplitter.splitDocuments(docs) + const store = new MemoryVectorStore(ollamaEmbedding) + await store.addDocuments(chunks) + + const resultsWithEmbeddings = await store.similaritySearch(query, 3) + + const searchResult = resultsWithEmbeddings.map((result) => { + return { + url: result.metadata.url, + content: result.pageContent + } + }) + + return searchResult +} + +const apiBraveSearch = async (braveApiKey: string, query: string) => { + const TOTAL_SEARCH_RESULTS = await totalSearchResults() + + const searchURL = `https://api.search.brave.com/res/v1/web/search?q=${query}&count=${TOTAL_SEARCH_RESULTS}` + + const abortController = new AbortController() + setTimeout(() => abortController.abort(), 20000) + + try { + const response = await fetch(searchURL, { + signal: abortController.signal, + headers: { + "X-Subscription-Token": braveApiKey, + Accept: "application/json", + } + }) + + if (!response.ok) { + return [] + } + + const data = await response.json() as BraveAPIResponse + + return data?.web?.results.map(result => ({ + title: result.title, + link: result.url, + content: result.description + })) + } catch (error) { + console.error('Brave API search failed:', error) + return [] + } +} diff --git a/src/web/web.ts b/src/web/web.ts index 6c48f1b..42d8ca9 100644 --- a/src/web/web.ts +++ b/src/web/web.ts @@ -6,6 +6,7 @@ import { webSogouSearch } from "./search-engines/sogou" import { webBraveSearch } from "./search-engines/brave" import { getWebsiteFromQuery, processSingleWebsite } from "./website" import { searxngSearch } from "./search-engines/searxng" +import { braveAPISearch } from "./search-engines/brave-api" const getHostName = (url: string) => { try { @@ -26,6 +27,8 @@ const searchWeb = (provider: string, query: string) => { return webBraveSearch(query) case "searxng": return searxngSearch(query) + case "brave-api": + return braveAPISearch(query) default: return webGoogleSearch(query) } From 5b87173868bb8fa3ef71a98415cf6ba50420f228 Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Fri, 13 Dec 2024 20:09:13 +0530 Subject: [PATCH 6/9] feat: Update README to describe Page Assist as a browser extension --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index add1101..0d5a238 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ [![Join dialoqbase #welcome](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/bu54382uBd) -Page Assist is an open-source Chrome Extension that provides a Sidebar and Web UI for your Local AI model. It allows you to interact with your model from any webpage. - +Page Assist is an open-source browser extension that provides a sidebar and web UI for your local AI model. It allows you to interact with your model from any webpage. ## Installation Page Assist supports Chromium-based browsers like Chrome, Brave, and Edge, as well as Firefox. From ccca2eafd3dee7aa0674f9325927fefd2ca216cc Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Sat, 14 Dec 2024 16:32:01 +0530 Subject: [PATCH 7/9] feat: Anonymize knowledge source content when marking as finished --- src/db/knowledge.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/db/knowledge.ts b/src/db/knowledge.ts index 3f90880..4e5188f 100644 --- a/src/db/knowledge.ts +++ b/src/db/knowledge.ts @@ -145,6 +145,12 @@ export const getKnowledgeById = async (id: string) => { export const updateKnowledgeStatus = async (id: string, status: string) => { const db = new PageAssistKnowledge() const knowledge = await db.getById(id) + if(status === "finished") { + knowledge.source = knowledge.source.map(e => ({ + ...e, + content: undefined, + })) + } await db.update({ ...knowledge, status From 43b4f076e9402fa92244e749090f7240774a8c1d Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Sat, 14 Dec 2024 18:30:27 +0530 Subject: [PATCH 8/9] feat: Add more options for chat messages to copy, download chat entirely --- bun.lockb | Bin 440402 -> 440402 bytes src/assets/locale/da/option.json | 17 +- src/assets/locale/de/option.json | 17 +- src/assets/locale/en/option.json | 17 +- src/assets/locale/es/option.json | 19 +- src/assets/locale/fa/option.json | 19 +- src/assets/locale/fr/option.json | 17 +- src/assets/locale/it/option.json | 17 +- src/assets/locale/ja-JP/option.json | 39 +++-- src/assets/locale/ko/option.json | 19 +- src/assets/locale/ml/option.json | 17 +- src/assets/locale/no/option.json | 19 +- src/assets/locale/pt-BR/option.json | 17 +- src/assets/locale/ru/option.json | 18 +- src/assets/locale/sv/option.json | 17 +- src/assets/locale/uk/option.json | 19 +- src/assets/locale/zh/option.json | 17 +- .../Common/{ShareBtn.tsx => ShareModal.tsx} | 124 ++++++------- src/components/Layouts/Header.tsx | 28 ++- src/components/Layouts/MoreOptions.tsx | 163 ++++++++++++++++++ 20 files changed, 509 insertions(+), 111 deletions(-) rename src/components/Common/{ShareBtn.tsx => ShareModal.tsx} (64%) create mode 100644 src/components/Layouts/MoreOptions.tsx diff --git a/bun.lockb b/bun.lockb index 8d4fe90e294d729224c4e4397fe940cc2bf9fa6d..a2dd2afd2e73621f84936a13cae325a70697b803 100644 GIT binary patch delta 41 vcmccgLF&>6sfHHD7N!>FEiBfpoQ!b>dIow%76$Dutt>#yy4|Ifjn5bWLEsH> delta 41 pcmccgLF&>6sfHHD7N!>FEiBfpoJrG_U0T`ri~%9-3%&pV diff --git a/src/assets/locale/da/option.json b/src/assets/locale/da/option.json index 5fc0281..17ad319 100644 --- a/src/assets/locale/da/option.json +++ b/src/assets/locale/da/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Venligst vælg en model for at forsæætte", "deleteHistoryConfirmation": "Er du sikker på at du vil slette denne historik?", "editHistoryTitle": "Indtast en ny titel", - "temporaryChat": "Midlertidig Chat" + "temporaryChat": "Midlertidig Chat", + "more": { + "copy": { + "group": "Kopier", + "asText": "Kopier som tekst", + "asMarkdown": "Kopier som Markdown", + "success": "Kopieret til udklipsholder!" + }, + "download": { + "group": "Download", + "text": "Tekstfil (.txt)", + "markdown": "Markdown (.md)", + "json": "JSON-fil (.json)" + }, + "share": "Del" + } } \ No newline at end of file diff --git a/src/assets/locale/de/option.json b/src/assets/locale/de/option.json index 4303931..708231f 100644 --- a/src/assets/locale/de/option.json +++ b/src/assets/locale/de/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Bitte wähle ein Modell aus, um fortzufahren", "deleteHistoryConfirmation": "Bist du sicher, dass du diesen Verlauf löschen möchtest?", "editHistoryTitle": "Gib einen neuen Titel ein", - "temporaryChat": "Temporärer Chat" + "temporaryChat": "Temporärer Chat", + "more": { + "copy": { + "group": "Kopieren", + "asText": "Als Text kopieren", + "asMarkdown": "Als Markdown kopieren", + "success": "In die Zwischenablage kopiert!" + }, + "download": { + "group": "Herunterladen", + "text": "Textdatei (.txt)", + "markdown": "Markdown (.md)", + "json": "JSON-Datei (.json)" + }, + "share": "Teilen" + } } \ No newline at end of file diff --git a/src/assets/locale/en/option.json b/src/assets/locale/en/option.json index 7d11938..debb1be 100644 --- a/src/assets/locale/en/option.json +++ b/src/assets/locale/en/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Please select a model to continue", "deleteHistoryConfirmation": "Are you sure you want to delete this history?", "editHistoryTitle": "Enter a new title", - "temporaryChat": "Temporary Chat" + "temporaryChat": "Temporary Chat", + "more": { + "copy": { + "group": "Copy", + "asText": "Copy as Text", + "asMarkdown": "Copy as Markdown", + "success": "Copied to clipboard!" + }, + "download": { + "group": "Download", + "text": "Text File (.txt)", + "markdown": "Markdown (.md)", + "json": "JSON File (.json)" + }, + "share": "Share" + } } \ No newline at end of file diff --git a/src/assets/locale/es/option.json b/src/assets/locale/es/option.json index d9ab8cf..3a2a395 100644 --- a/src/assets/locale/es/option.json +++ b/src/assets/locale/es/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Selecione un modelo para continuar", "deleteHistoryConfirmation": "¿Esta seguro que quiere borrar éste histórico?", "editHistoryTitle": "Ingrese un nuevo título", - "temporaryChat": "Chat Temporal" -} + "temporaryChat": "Chat Temporal", + "more": { + "copy": { + "group": "Copiar", + "asText": "Copiar como Texto", + "asMarkdown": "Copiar como Markdown", + "success": "¡Copiado al portapapeles!" + }, + "download": { + "group": "Descargar", + "text": "Archivo de Texto (.txt)", + "markdown": "Markdown (.md)", + "json": "Archivo JSON (.json)" + }, + "share": "Compartir" + } +} \ No newline at end of file diff --git a/src/assets/locale/fa/option.json b/src/assets/locale/fa/option.json index 5278cd0..7d1ee0e 100644 --- a/src/assets/locale/fa/option.json +++ b/src/assets/locale/fa/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "لطفا یک مدل را برای ادامه انتخاب کنید", "deleteHistoryConfirmation": "آیا مطمئن هستید که می خواهید این تاریخچه را حذف کنید؟", "editHistoryTitle": "یک عنوان جدید وارد کنید", - "temporaryChat": "گپ موقت" -} + "temporaryChat": "گپ موقت", + "more": { + "copy": { + "group": "کپی", + "asText": "کپی به صورت متن", + "asMarkdown": "کپی به صورت مارک‌داون", + "success": "در کلیپ‌بورد کپی شد!" + }, + "download": { + "group": "دانلود", + "text": "فایل متنی (.txt)", + "markdown": "مارک‌داون (.md)", + "json": "فایل JSON (.json)" + }, + "share": "اشتراک‌گذاری" + } +} \ No newline at end of file diff --git a/src/assets/locale/fr/option.json b/src/assets/locale/fr/option.json index ad374aa..a2b1dd0 100644 --- a/src/assets/locale/fr/option.json +++ b/src/assets/locale/fr/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Veuillez sélectionner un modèle pour continuer", "deleteHistoryConfirmation": "Êtes-vous sûr de vouloir supprimer cette historique ?", "editHistoryTitle": "Entrez un nouveau titre", - "temporaryChat": "Chat temporaire" + "temporaryChat": "Chat temporaire", + "more": { + "copy": { + "group": "Copier", + "asText": "Copier en texte", + "asMarkdown": "Copier en Markdown", + "success": "Copié dans le presse-papiers !" + }, + "download": { + "group": "Télécharger", + "text": "Fichier texte (.txt)", + "markdown": "Markdown (.md)", + "json": "Fichier JSON (.json)" + }, + "share": "Partager" + } } \ No newline at end of file diff --git a/src/assets/locale/it/option.json b/src/assets/locale/it/option.json index fb222c3..f95cf73 100644 --- a/src/assets/locale/it/option.json +++ b/src/assets/locale/it/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Scegliere un modello per continuare", "deleteHistoryConfirmation": "Sei sicuro che vuoi eliminare la cronologia?", "editHistoryTitle": "Inserisci un nuovo titolo", - "temporaryChat": "Chat Temporanea" + "temporaryChat": "Chat Temporanea", + "more": { + "copy": { + "group": "Copia", + "asText": "Copia come Testo", + "asMarkdown": "Copia come Markdown", + "success": "Copiato negli appunti!" + }, + "download": { + "group": "Scarica", + "text": "File di Testo (.txt)", + "markdown": "Markdown (.md)", + "json": "File JSON (.json)" + }, + "share": "Condividi" + } } \ No newline at end of file diff --git a/src/assets/locale/ja-JP/option.json b/src/assets/locale/ja-JP/option.json index 76dc343..6b7e7bb 100644 --- a/src/assets/locale/ja-JP/option.json +++ b/src/assets/locale/ja-JP/option.json @@ -1,13 +1,28 @@ { - "newChat": "新しいチャット", - "selectAPrompt": "プロンプトを選択", - "githubRepository": "GitHubリポジトリ", - "settings": "設定", - "sidebarTitle": "チャット履歴", - "error": "エラー", - "somethingWentWrong": "何かが間違っています", - "validationSelectModel": "続行するにはモデルを選択してください", - "deleteHistoryConfirmation": "この履歴を削除しますか?", - "editHistoryTitle": "新しいタイトルを入力", - "temporaryChat": "一時的なチャット" - } \ No newline at end of file + "newChat": "新しいチャット", + "selectAPrompt": "プロンプトを選択", + "githubRepository": "GitHubリポジトリ", + "settings": "設定", + "sidebarTitle": "チャット履歴", + "error": "エラー", + "somethingWentWrong": "何かが間違っています", + "validationSelectModel": "続行するにはモデルを選択してください", + "deleteHistoryConfirmation": "この履歴を削除しますか?", + "editHistoryTitle": "新しいタイトルを入力", + "temporaryChat": "一時的なチャット", + "more": { + "copy": { + "group": "コピー", + "asText": "テキストとしてコピー", + "asMarkdown": "Markdownとしてコピー", + "success": "クリップボードにコピーしました!" + }, + "download": { + "group": "ダウンロード", + "text": "テキストファイル (.txt)", + "markdown": "Markdownファイル (.md)", + "json": "JSONファイル (.json)" + }, + "share": "共有" + } +} \ No newline at end of file diff --git a/src/assets/locale/ko/option.json b/src/assets/locale/ko/option.json index 2db30cc..d93fcc3 100644 --- a/src/assets/locale/ko/option.json +++ b/src/assets/locale/ko/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "계속하려면 모델을 선택하세요", "deleteHistoryConfirmation": "이 기록을 삭제하시겠습니까?", "editHistoryTitle": "새 제목 입력", - "temporaryChat": "임시 채팅" -} + "temporaryChat": "임시 채팅", + "more": { + "copy": { + "group": "복사", + "asText": "텍스트로 복사", + "asMarkdown": "마크다운으로 복사", + "success": "클립보드에 복사되었습니다!" + }, + "download": { + "group": "다운로드", + "text": "텍스트 파일 (.txt)", + "markdown": "마크다운 (.md)", + "json": "JSON 파일 (.json)" + }, + "share": "공유" + } +} \ No newline at end of file diff --git a/src/assets/locale/ml/option.json b/src/assets/locale/ml/option.json index 1004b13..53d8b4d 100644 --- a/src/assets/locale/ml/option.json +++ b/src/assets/locale/ml/option.json @@ -9,5 +9,20 @@ "deleteHistoryConfirmation": "നിങ്ങളുടെ ചാറ്റ് ചരിത്രം ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ?", "editHistoryTitle": "ചാറ്റ് title എഡിറ്റുചെയ്യുക", "validationSelectModel": "തുടരുന്നതിന് ഒരു മോഡല്‍ തിരഞ്ഞെടുക്കുക", - "temporaryChat": "താൽക്കാലിക ചാറ്റ്" + "temporaryChat": "താൽക്കാലിക ചാറ്റ്", + "more": { + "copy": { + "group": "പകർത്തുക", + "asText": "ടെക്സ്റ്റായി പകർത്തുക", + "asMarkdown": "മാർക്ക്ഡൗൺ ആയി പകർത്തുക", + "success": "ക്ലിപ്പ്ബോർഡിലേക്ക് പകർത്തി!" + }, + "download": { + "group": "ഡൗൺലോഡ്", + "text": "ടെക്സ്റ്റ് ഫയൽ (.txt)", + "markdown": "മാർക്ക്ഡൗൺ (.md)", + "json": "JSON ഫയൽ (.json)" + }, + "share": "പങ്കുവയ്ക്കുക" + } } \ No newline at end of file diff --git a/src/assets/locale/no/option.json b/src/assets/locale/no/option.json index 64adb7b..fad0201 100644 --- a/src/assets/locale/no/option.json +++ b/src/assets/locale/no/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Vennligst velg en modell for å fortsette", "deleteHistoryConfirmation": "Er du sikker på at du vil slette denne historikken?", "editHistoryTitle": "Skriv inn en ny tittel", - "temporaryChat": "Midlertidig Chat" -} + "temporaryChat": "Midlertidig Chat", + "more": { + "copy": { + "group": "Kopier", + "asText": "Kopier som tekst", + "asMarkdown": "Kopier som Markdown", + "success": "Kopiert til utklippstavlen!" + }, + "download": { + "group": "Last ned", + "text": "Tekstfil (.txt)", + "markdown": "Markdown (.md)", + "json": "JSON-fil (.json)" + }, + "share": "Del" + } +} \ No newline at end of file diff --git a/src/assets/locale/pt-BR/option.json b/src/assets/locale/pt-BR/option.json index eeffe1c..8702733 100644 --- a/src/assets/locale/pt-BR/option.json +++ b/src/assets/locale/pt-BR/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Por favor, selecione um modelo para continuar", "deleteHistoryConfirmation": "Tem certeza de que deseja excluir este histórico?", "editHistoryTitle": "Digite um novo título", - "temporaryChat": "Chat Temporário" + "temporaryChat": "Chat Temporário", + "more": { + "copy": { + "group": "Copiar", + "asText": "Copiar como Texto", + "asMarkdown": "Copiar como Markdown", + "success": "Copiado para área de transferência!" + }, + "download": { + "group": "Baixar", + "text": "Arquivo de Texto (.txt)", + "markdown": "Markdown (.md)", + "json": "Arquivo JSON (.json)" + }, + "share": "Compartilhar" + } } \ No newline at end of file diff --git a/src/assets/locale/ru/option.json b/src/assets/locale/ru/option.json index bd8f987..a14a9d4 100644 --- a/src/assets/locale/ru/option.json +++ b/src/assets/locale/ru/option.json @@ -9,5 +9,19 @@ "validationSelectModel": "Пожалуйста, выберите модель, чтобы продолжить", "deleteHistoryConfirmation": "Вы уверены, что хотите удалить эту историю?", "editHistoryTitle": "Введите новое название", - "temporaryChat": "Временный чат" -} + "temporaryChat": "Временный чат", + "more": { + "copy": { + "group": "Копировать", + "asText": "Копировать как текст", + "asMarkdown": "Копировать как Markdown", + "success": "Скопировано в буфер обмена!" + }, + "download": { + "group": "Скачать", + "text": "Текстовый файл (.txt)", + "markdown": "Markdown (.md)", + "json": "JSON файл (.json)" + }, + "share": "Поделиться" + }} diff --git a/src/assets/locale/sv/option.json b/src/assets/locale/sv/option.json index 98e1012..96d873a 100644 --- a/src/assets/locale/sv/option.json +++ b/src/assets/locale/sv/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Vänligen välj en modell för att fortsätta", "deleteHistoryConfirmation": "Är du säker på att du vill radera denna historik?", "editHistoryTitle": "Ange en ny titel", - "temporaryChat": "Tillfällig chatt" + "temporaryChat": "Tillfällig chatt", + "more": { + "copy": { + "group": "Kopiera", + "asText": "Kopiera som text", + "asMarkdown": "Kopiera som Markdown", + "success": "Kopierat till urklipp!" + }, + "download": { + "group": "Ladda ner", + "text": "Textfil (.txt)", + "markdown": "Markdown (.md)", + "json": "JSON-fil (.json)" + }, + "share": "Dela" + } } diff --git a/src/assets/locale/uk/option.json b/src/assets/locale/uk/option.json index 22a76d4..0823889 100644 --- a/src/assets/locale/uk/option.json +++ b/src/assets/locale/uk/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "Будь ласка, виберіть модель для продовження", "deleteHistoryConfirmation": "Ви впевнені, що хочете видалити цю історію?", "editHistoryTitle": "Введіть нову назву", - "temporaryChat": "Тимчасовий чат" -} + "temporaryChat": "Тимчасовий чат", + "more": { + "copy": { + "group": "Копіювати", + "asText": "Копіювати як текст", + "asMarkdown": "Копіювати як Markdown", + "success": "Скопійовано в буфер обміну!" + }, + "download": { + "group": "Завантажити", + "text": "Текстовий файл (.txt)", + "markdown": "Markdown (.md)", + "json": "JSON файл (.json)" + }, + "share": "Поділитися" + } +} \ No newline at end of file diff --git a/src/assets/locale/zh/option.json b/src/assets/locale/zh/option.json index cba6731..d4ed2ee 100644 --- a/src/assets/locale/zh/option.json +++ b/src/assets/locale/zh/option.json @@ -9,5 +9,20 @@ "validationSelectModel": "请选择一个模型以继续", "deleteHistoryConfirmation": "你确定要删除这个历史记录吗?", "editHistoryTitle": "输入一个新的标题", - "temporaryChat": "临时聊天" + "temporaryChat": "临时聊天", + "more": { + "copy": { + "group": "复制", + "asText": "复制为文本", + "asMarkdown": "复制为 Markdown", + "success": "已复制到剪贴板!" + }, + "download": { + "group": "下载", + "text": "文本文件 (.txt)", + "markdown": "Markdown 文件 (.md)", + "json": "JSON 文件 (.json)" + }, + "share": "分享" + } } \ No newline at end of file diff --git a/src/components/Common/ShareBtn.tsx b/src/components/Common/ShareModal.tsx similarity index 64% rename from src/components/Common/ShareBtn.tsx rename to src/components/Common/ShareModal.tsx index e1146a0..3808d3b 100644 --- a/src/components/Common/ShareBtn.tsx +++ b/src/components/Common/ShareModal.tsx @@ -14,6 +14,8 @@ import fetcher from "@/libs/fetcher" type Props = { messages: Message[] historyId: string + open: boolean + setOpen: (state: boolean) => void } const reformatMessages = (messages: Message[], username: string) => { @@ -77,9 +79,13 @@ export const PlaygroundMessage = ( ) } -export const ShareBtn: React.FC = ({ messages, historyId }) => { +export const ShareModal: React.FC = ({ + messages, + historyId, + open, + setOpen +}) => { const { t } = useTranslation("common") - const [open, setOpen] = useState(false) const [form] = Form.useForm() const name = Form.useWatch("name", form) @@ -142,75 +148,55 @@ export const ShareBtn: React.FC = ({ messages, historyId }) => { }) return ( - <> - - - + setOpen(false)}> +
+ + + + + + - setOpen(false)}> - - - - - - - - - -
-
- {messages.map((message, index) => ( - - ))} -
+ +
+
+ {messages.map((message, index) => ( + + ))}
- +
+
- -
- -
-
- - - + +
+ +
+
+ + ) } diff --git a/src/components/Layouts/Header.tsx b/src/components/Layouts/Header.tsx index 72f31da..0001ab7 100644 --- a/src/components/Layouts/Header.tsx +++ b/src/components/Layouts/Header.tsx @@ -19,10 +19,10 @@ import { fetchChatModels } from "~/services/ollama" import { useMessageOption } from "~/hooks/useMessageOption" import { Select, Tooltip } from "antd" import { getAllPrompts } from "@/db" -import { ShareBtn } from "~/components/Common/ShareBtn" import { ProviderIcons } from "../Common/ProviderIcon" import { NewChat } from "./NewChat" import { PageAssistSelect } from "../Select" +import { MoreOptions } from "./MoreOptions" type Props = { setSidebarOpen: (open: boolean) => void setOpenModelSettings: (open: boolean) => void @@ -50,7 +50,11 @@ export const Header: React.FC = ({ historyId, temporaryChat } = useMessageOption() - const { data: models, isLoading: isModelsLoading, refetch } = useQuery({ + const { + data: models, + isLoading: isModelsLoading, + refetch + } = useQuery({ queryKey: ["fetchModel"], queryFn: () => fetchChatModels({ returnEmpty: true }), refetchIntervalInBackground: false, @@ -134,7 +138,6 @@ export const Header: React.FC = ({ ), value: model.model }))} - onRefresh={() => { refetch() }} @@ -189,6 +192,19 @@ export const Header: React.FC = ({
+ {/* {pathname === "/" && + messages.length > 0 && + !streaming && + shareModeEnabled && ( + + )} */} + {messages.length > 0 && !streaming && ( + + )} {!hideCurrentChatModelSettings && ( )} - {pathname === "/" && - messages.length > 0 && - !streaming && - shareModeEnabled && ( - - )} { + return messages + .map((msg) => { + const text = `${msg.isBot ? msg.name : "You"}: ${msg.message}` + return text + }) + .join("\n\n") +} + +const formatAsMarkdown = (messages: Message[]) => { + return messages + .map((msg) => { + let content = `**${msg.isBot ? msg.name : "You"}**:\n${msg.message}` + + if (msg.images && msg.images.length > 0) { + const imageMarkdown = msg.images + .filter((img) => img.length > 0) + .map((img) => `\n\n![Image](${img})`) + .join("\n") + content += imageMarkdown + } + + return content + }) + .join("\n\n") +} + +const downloadFile = (content: string, filename: string) => { + const blob = new Blob([content], { type: "text/plain;charset=utf-8" }) + const url = URL.createObjectURL(blob) + const link = document.createElement("a") + link.href = url + link.download = filename + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + URL.revokeObjectURL(url) +} + +export const MoreOptions = ({ + shareModeEnabled = false, + historyId, + messages +}: MoreOptionsProps) => { + const { t } = useTranslation("option") + const [onShareOpen, setOnShareOpen] = useState(false) + const baseItems: MenuProps["items"] = [ + { + type: "group", + label: t("more.copy.group"), + children: [ + { + key: "copy-text", + label: t("more.copy.asText"), + icon: , + onClick: () => { + navigator.clipboard.writeText(formatAsText(messages)) + message.success(t("more.copy.success")) + } + }, + { + key: "copy-markdown", + label: t("more.copy.asMarkdown"), + icon: , + onClick: () => { + navigator.clipboard.writeText(formatAsMarkdown(messages)) + message.success(t("more.copy.success")) + } + } + ] + }, + { + type: "divider" + }, + { + type: "group", + label: t("more.download.group"), + children: [ + { + key: "download-txt", + label: t("more.download.text"), + icon: , + onClick: () => { + downloadFile(formatAsText(messages), "chat.txt") + } + }, + { + key: "download-md", + label: t("more.download.markdown"), + icon: , + onClick: () => { + downloadFile(formatAsMarkdown(messages), "chat.md") + } + }, + { + key: "download-json", + label: t("more.download.json"), + icon: , + onClick: () => { + const jsonContent = JSON.stringify(messages, null, 2) + downloadFile(jsonContent, "chat.json") + } + } + ] + } + ] + + const shareItem = { + type: "divider" + } as const + + const shareOption = { + key: "share", + label: t("more.share"), + icon: , + onClick: () => { + setOnShareOpen(true) + } + } + + const items = shareModeEnabled + ? [...baseItems, shareItem, shareOption] + : baseItems + + return ( + <> + + + + + + ) +} From 81244906558cc653a44c49eaf437f7cc87f44f4a Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Sun, 15 Dec 2024 13:09:37 +0530 Subject: [PATCH 9/9] feat: Improve system reset functionality in settings --- .../Option/Settings/general-settings.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/Option/Settings/general-settings.tsx b/src/components/Option/Settings/general-settings.tsx index e5b6d35..45bd9c2 100644 --- a/src/components/Option/Settings/general-settings.tsx +++ b/src/components/Option/Settings/general-settings.tsx @@ -271,13 +271,13 @@ export const GeneralSettings = () => { queryKey: ["fetchChatHistory"] }) clearChat() - } - try { - await browser.storage.sync.clear() - await browser.storage.local.clear() - await browser.storage.session.clear() - } catch (e) { - console.log("Error clearing storage:", e) + try { + await browser.storage.sync.clear() + await browser.storage.local.clear() + await browser.storage.session.clear() + } catch (e) { + console.log("Error clearing storage:", e) + } } }} className="bg-red-500 dark:bg-red-600 text-white dark:text-gray-200 px-4 py-2 rounded-md">