diff --git a/src/assets/locale/en/common.json b/src/assets/locale/en/common.json index 5cd332f..ffa6e81 100644 --- a/src/assets/locale/en/common.json +++ b/src/assets/locale/en/common.json @@ -51,7 +51,7 @@ "chatWithCurrentPage": "Chat with current page", "beta": "Beta", "tts": "Read aloud", - "currentChatModelSettings":"Current Chat Model Settings", + "currentChatModelSettings": "Current Chat Model Settings", "modelSettings": { "label": "Model Settings", "description": "Set the model options globally for all chats", diff --git a/src/assets/locale/en/knowledge.json b/src/assets/locale/en/knowledge.json index 7e66f13..a29cf89 100644 --- a/src/assets/locale/en/knowledge.json +++ b/src/assets/locale/en/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "Pending", "finished": "Finished", - "processing": "Processing" + "processing": "Processing", + "failed": "Failed" }, "addKnowledge": "Add Knowledge", "form": { diff --git a/src/assets/locale/en/settings.json b/src/assets/locale/en/settings.json index fb798d2..9d38d57 100644 --- a/src/assets/locale/en/settings.json +++ b/src/assets/locale/en/settings.json @@ -1,307 +1,313 @@ { - "generalSettings": { - "title": "General Settings", - "settings": { - "heading": "Web UI Settings", - "speechRecognitionLang": { - "label": "Speech Recognition Language", - "placeholder": "Select a language" - }, - "language": { - "label": "Language", - "placeholder": "Select a language" - }, - "darkMode": { - "label": "Change Theme", - "options": { - "light": "Light", - "dark": "Dark" - } - }, - "copilotResumeLastChat": { - "label": "Resume the last chat when opening the SidePanel (Copilot)" - }, - "hideCurrentChatModelSettings": { - "label": "Hide the current Chat Model Settings" - } - }, - "webSearch": { - "heading": "Manage Web Search", - "searchMode": { - "label": "Perform Simple Internet Search" - }, - "provider": { - "label": "Search Engine", - "placeholder": "Select a search engine" - }, - "totalSearchResults": { - "label": "Total Search Results", - "placeholder": "Enter Total Search Results" - }, - "visitSpecificWebsite": { - "label": "Visit the website mentioned in the message" - } - }, - "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." - }, - "export": { - "label": "Export Chat History, Knowledge Base, and Prompts", - "button": "Export Data", - "success": "Export Success" - }, - "import": { - "label": "Import Chat History, Knowledge Base, and Prompts", - "button": "Import Data", - "success": "Import Success", - "error": "Import Error" - } - }, - "tts": { - "heading": "Text-to-Speech Settings", - "ttsEnabled": { - "label": "Enable Text-to-Speech" - }, - "ttsProvider": { - "label": "Text-to-Speech Provider", - "placeholder": "Select a provider" - }, - "ttsVoice": { - "label": "Text-to-Speech Voice", - "placeholder": "Select a voice" - }, - "ssmlEnabled": { - "label": "Enable SSML (Speech Synthesis Markup Language)" - } + "generalSettings": { + "title": "General Settings", + "settings": { + "heading": "Web UI Settings", + "speechRecognitionLang": { + "label": "Speech Recognition Language", + "placeholder": "Select a language" + }, + "language": { + "label": "Language", + "placeholder": "Select a language" + }, + "darkMode": { + "label": "Change Theme", + "options": { + "light": "Light", + "dark": "Dark" } + }, + "copilotResumeLastChat": { + "label": "Resume the last chat when opening the SidePanel (Copilot)" + }, + "hideCurrentChatModelSettings": { + "label": "Hide the current Chat Model Settings" + }, + "restoreLastChatModel": { + "label": "Restore last used model for previous chats" + }, + "sendNotificationAfterIndexing": { + "label": "Send Notification After Finishing Processing the Knowledge Base" + } }, - "manageModels": { - "title": "Manage Models", - "addBtn": "Add New Model", - "columns": { - "name": "Name", - "digest": "Digest", - "modifiedAt": "Modified At", - "size": "Size", - "actions": "Actions" - }, - "expandedColumns": { - "parentModel": "Parent Model", - "format": "Format", - "family": "Family", - "parameterSize": "Parameter Size", - "quantizationLevel": "Quantization Level" - }, - "tooltip": { - "delete": "Delete Model", - "repull": "Re-Pull Model" - }, - "confirm": { - "delete": "Are you sure you want to delete this model?", - "repull": "Are you sure you want to re-pull this model?" - }, - "modal": { - "title": "Add New Model", - "placeholder": "Enter Model Name", - "pull": "Pull Model" - }, - "notification": { - "pullModel": "Pulling Model", - "pullModelDescription": "Pulling {{modelName}} model. For more details, check the extension icon.", - "success": "Success", - "error": "Error", - "successDescription": "Successfully pulled the model", - "successDeleteDescription": "Successfully deleted the model", - "someError": "Something went wrong. Please try again later" - } + "webSearch": { + "heading": "Manage Web Search", + "searchMode": { + "label": "Perform Simple Internet Search" + }, + "provider": { + "label": "Search Engine", + "placeholder": "Select a search engine" + }, + "totalSearchResults": { + "label": "Total Search Results", + "placeholder": "Enter Total Search Results" + }, + "visitSpecificWebsite": { + "label": "Visit the website mentioned in the message" + } }, - "managePrompts": { - "title": "Manage Prompts", - "addBtn": "Add New Prompt", - "option1": "Normal", - "option2": "RAG", - "questionPrompt": "Question Prompt", - "columns": { - "title": "Title", - "prompt": "Prompt", - "type": "Prompt Type", - "actions": "Actions" - }, - "systemPrompt": "System Prompt", - "quickPrompt": "Quick Prompt", - "tooltip": { - "delete": "Delete Prompt", - "edit": "Edit Prompt" - }, - "confirm": { - "delete": "Are you sure you want to delete this prompt? This action cannot be undone." - }, - "modal": { - "addTitle": "Add New Prompt", - "editTitle": "Edit Prompt" - }, - "form": { - "title": { - "label": "Title", - "placeholder": "My Awesome Prompt", - "required": "Please enter a title" - }, - "prompt": { - "label": "Prompt", - "placeholder": "Enter Prompt", - "required": "Please enter a prompt", - "help": "You can use {key} as variable in your prompt." - }, - "isSystem": { - "label": "Is System Prompt" - }, - "btnSave": { - "saving": "Adding Prompt...", - "save": "Add Prompt" - }, - "btnEdit": { - "saving": "Updating Prompt...", - "save": "Update Prompt" - } - }, - "notification": { - "addSuccess": "Prompt Added", - "addSuccessDesc": "Prompt has been added successfully", - "error": "Error", - "someError": "Something went wrong. Please try again later", - "updatedSuccess": "Prompt Updated", - "updatedSuccessDesc": "Prompt has been updated successfully", - "deletedSuccess": "Prompt Deleted", - "deletedSuccessDesc": "Prompt has been deleted successfully" - } + "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." + }, + "export": { + "label": "Export Chat History, Knowledge Base, and Prompts", + "button": "Export Data", + "success": "Export Success" + }, + "import": { + "label": "Import Chat History, Knowledge Base, and Prompts", + "button": "Import Data", + "success": "Import Success", + "error": "Import Error" + } }, - "manageShare": { - "title": "Manage Share", - "heading": "Configure Page Share URL", - "form": { - "url": { - "label": "Page Share URL", - "placeholder": "Enter Page Share URL", - "required": "Please input your Page Share URL!", - "help": "For privacy reasons, you can self-host the page share and provide the URL here. Learn More." - } - }, - "webshare": { - "heading": "Web Share", - "columns": { - "title": "Title", - "url": "URL", - "actions": "Actions" - }, - "tooltip": { - "delete": "Delete Share" - }, - "confirm": { - "delete": "Are you sure you want to delete this share? This action cannot be undone." - }, - "label": "Manage Page Share", - "description": "Enable or disable the page share feature" - }, - "notification": { - "pageShareSuccess": "Page Share URL updated successfully", - "someError": "Something went wrong. Please try again later", - "webShareDeleteSuccess": "Web Share deleted successfully" - } - }, - "ollamaSettings": { - "title": "Ollama Settings", - "heading": "Configure Ollama", - "settings": { - "ollamaUrl": { - "label": "Ollama URL", - "placeholder": "Enter Ollama URL" - }, - "advanced": { - "label": "Advance Ollama URL Configuration", - "urlRewriteEnabled": { - "label": "Enable or Disable Custom Origin URL" - }, - "rewriteUrl": { - "label": "Custom Origin URL", - "placeholder": "Enter Custom Origin URL" - }, - "headers": { - "label": "Custom Headers", - "add": "Add Header", - "key": { - "label": "Header Key", - "placeholder": "Authorization" - }, - "value": { - "label": "Header Value", - "placeholder": "Bearer token" - } - }, - "help": "If you have connection issues with Ollama on Page Assist, you can configure a custom origin URL. To learn more about the configuration, click here." - } - } - }, - "manageSearch": { - "title": "Manage Web Search", - "heading": "Configure Web Search" - }, - "about": { - "title": "About", - "heading": "About", - "chromeVersion": "Page Assist Version", - "ollamaVersion": "Ollama Version", - "support": "You can support the Page Assist project by donating or sponsoring through the following platforms:", - "koFi": "Support on Ko-fi", - "githubSponsor": "Sponsor on GitHub", - "githubRepo": "GitHub Repository" - }, - "manageKnowledge": { - "title": "Manage Knowledge", - "heading": "Configure Knowledge Base" - }, - "rag": { - "title": "RAG Settings", - "ragSettings": { - "label": "RAG Settings", - "model": { - "label": "Embedding Model", - "required": "Please select a model", - "help": "Highly recommended to use embedding models like `nomic-embed-text`.", - "placeholder": "Select a model" - }, - "chunkSize": { - "label": "Chunk Size", - "placeholder": "Enter Chunk Size", - "required": "Please enter a chunk size" - }, - "chunkOverlap": { - "label": "Chunk Overlap", - "placeholder": "Enter Chunk Overlap", - "required": "Please enter a chunk overlap" - } - }, - "prompt": { - "label": "Configure RAG Prompt", - "option1": "Normal", - "option2": "Web", - "alert": "Configuring the system prompt here is deprecated. Please use the Manage Prompts section to add or edit prompts. This section will be removed in a future release", - "systemPrompt": "System Prompt", - "systemPromptPlaceholder": "Enter System Prompt", - "webSearchPrompt": "Web Search Prompt", - "webSearchPromptHelp": "Do not remove `{search_results}` from the prompt.", - "webSearchPromptError": "Please enter a web search prompt", - "webSearchPromptPlaceholder": "Enter Web Search Prompt", - "webSearchFollowUpPrompt": "Web Search Follow Up Prompt", - "webSearchFollowUpPromptHelp": "Do not remove `{chat_history}` and `{question}` from the prompt.", - "webSearchFollowUpPromptError": "Please input your Web Search Follow Up Prompt!", - "webSearchFollowUpPromptPlaceholder": "Your Web Search Follow Up Prompt" - } - }, - "chromeAiSettings": { - "title": "Chrome AI Settings" + "tts": { + "heading": "Text-to-Speech Settings", + "ttsEnabled": { + "label": "Enable Text-to-Speech" + }, + "ttsProvider": { + "label": "Text-to-Speech Provider", + "placeholder": "Select a provider" + }, + "ttsVoice": { + "label": "Text-to-Speech Voice", + "placeholder": "Select a voice" + }, + "ssmlEnabled": { + "label": "Enable SSML (Speech Synthesis Markup Language)" + } } -} \ No newline at end of file + }, + "manageModels": { + "title": "Manage Models", + "addBtn": "Add New Model", + "columns": { + "name": "Name", + "digest": "Digest", + "modifiedAt": "Modified At", + "size": "Size", + "actions": "Actions" + }, + "expandedColumns": { + "parentModel": "Parent Model", + "format": "Format", + "family": "Family", + "parameterSize": "Parameter Size", + "quantizationLevel": "Quantization Level" + }, + "tooltip": { + "delete": "Delete Model", + "repull": "Re-Pull Model" + }, + "confirm": { + "delete": "Are you sure you want to delete this model?", + "repull": "Are you sure you want to re-pull this model?" + }, + "modal": { + "title": "Add New Model", + "placeholder": "Enter Model Name", + "pull": "Pull Model" + }, + "notification": { + "pullModel": "Pulling Model", + "pullModelDescription": "Pulling {{modelName}} model. For more details, check the extension icon.", + "success": "Success", + "error": "Error", + "successDescription": "Successfully pulled the model", + "successDeleteDescription": "Successfully deleted the model", + "someError": "Something went wrong. Please try again later" + } + }, + "managePrompts": { + "title": "Manage Prompts", + "addBtn": "Add New Prompt", + "option1": "Normal", + "option2": "RAG", + "questionPrompt": "Question Prompt", + "columns": { + "title": "Title", + "prompt": "Prompt", + "type": "Prompt Type", + "actions": "Actions" + }, + "systemPrompt": "System Prompt", + "quickPrompt": "Quick Prompt", + "tooltip": { + "delete": "Delete Prompt", + "edit": "Edit Prompt" + }, + "confirm": { + "delete": "Are you sure you want to delete this prompt? This action cannot be undone." + }, + "modal": { + "addTitle": "Add New Prompt", + "editTitle": "Edit Prompt" + }, + "form": { + "title": { + "label": "Title", + "placeholder": "My Awesome Prompt", + "required": "Please enter a title" + }, + "prompt": { + "label": "Prompt", + "placeholder": "Enter Prompt", + "required": "Please enter a prompt", + "help": "You can use {key} as variable in your prompt." + }, + "isSystem": { + "label": "Is System Prompt" + }, + "btnSave": { + "saving": "Adding Prompt...", + "save": "Add Prompt" + }, + "btnEdit": { + "saving": "Updating Prompt...", + "save": "Update Prompt" + } + }, + "notification": { + "addSuccess": "Prompt Added", + "addSuccessDesc": "Prompt has been added successfully", + "error": "Error", + "someError": "Something went wrong. Please try again later", + "updatedSuccess": "Prompt Updated", + "updatedSuccessDesc": "Prompt has been updated successfully", + "deletedSuccess": "Prompt Deleted", + "deletedSuccessDesc": "Prompt has been deleted successfully" + } + }, + "manageShare": { + "title": "Manage Share", + "heading": "Configure Page Share URL", + "form": { + "url": { + "label": "Page Share URL", + "placeholder": "Enter Page Share URL", + "required": "Please input your Page Share URL!", + "help": "For privacy reasons, you can self-host the page share and provide the URL here. Learn More." + } + }, + "webshare": { + "heading": "Web Share", + "columns": { + "title": "Title", + "url": "URL", + "actions": "Actions" + }, + "tooltip": { + "delete": "Delete Share" + }, + "confirm": { + "delete": "Are you sure you want to delete this share? This action cannot be undone." + }, + "label": "Manage Page Share", + "description": "Enable or disable the page share feature" + }, + "notification": { + "pageShareSuccess": "Page Share URL updated successfully", + "someError": "Something went wrong. Please try again later", + "webShareDeleteSuccess": "Web Share deleted successfully" + } + }, + "ollamaSettings": { + "title": "Ollama Settings", + "heading": "Configure Ollama", + "settings": { + "ollamaUrl": { + "label": "Ollama URL", + "placeholder": "Enter Ollama URL" + }, + "advanced": { + "label": "Advance Ollama URL Configuration", + "urlRewriteEnabled": { + "label": "Enable or Disable Custom Origin URL" + }, + "rewriteUrl": { + "label": "Custom Origin URL", + "placeholder": "Enter Custom Origin URL" + }, + "headers": { + "label": "Custom Headers", + "add": "Add Header", + "key": { + "label": "Header Key", + "placeholder": "Authorization" + }, + "value": { + "label": "Header Value", + "placeholder": "Bearer token" + } + }, + "help": "If you have connection issues with Ollama on Page Assist, you can configure a custom origin URL. To learn more about the configuration, click here." + } + } + }, + "manageSearch": { + "title": "Manage Web Search", + "heading": "Configure Web Search" + }, + "about": { + "title": "About", + "heading": "About", + "chromeVersion": "Page Assist Version", + "ollamaVersion": "Ollama Version", + "support": "You can support the Page Assist project by donating or sponsoring through the following platforms:", + "koFi": "Support on Ko-fi", + "githubSponsor": "Sponsor on GitHub", + "githubRepo": "GitHub Repository" + }, + "manageKnowledge": { + "title": "Manage Knowledge", + "heading": "Configure Knowledge Base" + }, + "rag": { + "title": "RAG Settings", + "ragSettings": { + "label": "RAG Settings", + "model": { + "label": "Embedding Model", + "required": "Please select a model", + "help": "Highly recommended to use embedding models like `nomic-embed-text`.", + "placeholder": "Select a model" + }, + "chunkSize": { + "label": "Chunk Size", + "placeholder": "Enter Chunk Size", + "required": "Please enter a chunk size" + }, + "chunkOverlap": { + "label": "Chunk Overlap", + "placeholder": "Enter Chunk Overlap", + "required": "Please enter a chunk overlap" + } + }, + "prompt": { + "label": "Configure RAG Prompt", + "option1": "Normal", + "option2": "Web", + "alert": "Configuring the system prompt here is deprecated. Please use the Manage Prompts section to add or edit prompts. This section will be removed in a future release", + "systemPrompt": "System Prompt", + "systemPromptPlaceholder": "Enter System Prompt", + "webSearchPrompt": "Web Search Prompt", + "webSearchPromptHelp": "Do not remove `{search_results}` from the prompt.", + "webSearchPromptError": "Please enter a web search prompt", + "webSearchPromptPlaceholder": "Enter Web Search Prompt", + "webSearchFollowUpPrompt": "Web Search Follow Up Prompt", + "webSearchFollowUpPromptHelp": "Do not remove `{chat_history}` and `{question}` from the prompt.", + "webSearchFollowUpPromptError": "Please input your Web Search Follow Up Prompt!", + "webSearchFollowUpPromptPlaceholder": "Your Web Search Follow Up Prompt" + } + }, + "chromeAiSettings": { + "title": "Chrome AI Settings" + } +} diff --git a/src/assets/locale/es/knowledge.json b/src/assets/locale/es/knowledge.json index 86ddbf3..13eb6e5 100644 --- a/src/assets/locale/es/knowledge.json +++ b/src/assets/locale/es/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "Pendiente", "finished": "Finalizado", - "processing": "Procesando" + "processing": "Procesando", + "failed": "Fallido" }, "addKnowledge": "Agregar Conocimiento", "form": { diff --git a/src/assets/locale/es/settings.json b/src/assets/locale/es/settings.json index f169e88..e4df0e0 100644 --- a/src/assets/locale/es/settings.json +++ b/src/assets/locale/es/settings.json @@ -1,307 +1,313 @@ { - "generalSettings": { - "title": "Configuraciones Generales", - "settings": { - "heading": "Configuraciones de la Interfaz Web", - "speechRecognitionLang": { - "label": "Idioma de Reconocimiento de Voz", - "placeholder": "Selecione un idioma" - }, - "language": { - "label": "Idioma", - "placeholder": "Selecione un idioma" - }, - "darkMode": { - "label": "Cambiar Tema", - "options": { - "light": "Claro", - "dark": "Oscuro" - } - }, - "copilotResumeLastChat": { - "label": "Retomar el último chat al abrir el Panel Lateral (Copilot)" - }, - "hideCurrentChatModelSettings": { - "label": "Ocultar Configuraciones del Modelo de Chat Actual" - } - }, - "webSearch": { - "heading": "Manejo de la busqueda Web", - "searchMode": { - "label": "Realizar busquedas Simples en Internet" - }, - "provider": { - "label": "Motor de Busqueda", - "placeholder": "Selecione un motor de busqueda" - }, - "totalSearchResults": { - "label": "Resultados totales de la busqueda", - "placeholder": "Ingresar el total de Resultados de la busqueda" - }, - "visitSpecificWebsite": { - "label": "Visita el sitio web mencionado en el mensaje" - } - }, - "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." - }, - "export": { - "label": "Exportar Histórico del Chat, Base de Conocimiento y Prompts", - "button": "Exportar Datos", - "success": "Exportación exitosa" - }, - "import": { - "label": "Importar Histórico del Chat, Base de Conocimiento y Prompts", - "button": "Importar Datos", - "success": "Importación existosa", - "error": "Error de importación" - } - }, - "tts": { - "heading": "Configuraciones de Text-to-speech", - "ttsEnabled": { - "label": "Habilitar Texto-a-Voz" - }, - "ttsProvider": { - "label": "Proveedor de Text-to-speech", - "placeholder": "Selecione un proveedor" - }, - "ttsVoice": { - "label": "Voz de Text-to-speech", - "placeholder": "Selecione una voz" - }, - "ssmlEnabled": { - "label": "Habilitar SSML (Speech Synthesis Markup Language)" - } + "generalSettings": { + "title": "Configuraciones Generales", + "settings": { + "heading": "Configuraciones de la Interfaz Web", + "speechRecognitionLang": { + "label": "Idioma de Reconocimiento de Voz", + "placeholder": "Selecione un idioma" + }, + "language": { + "label": "Idioma", + "placeholder": "Selecione un idioma" + }, + "darkMode": { + "label": "Cambiar Tema", + "options": { + "light": "Claro", + "dark": "Oscuro" } + }, + "copilotResumeLastChat": { + "label": "Retomar el último chat al abrir el Panel Lateral (Copilot)" + }, + "hideCurrentChatModelSettings": { + "label": "Ocultar Configuraciones del Modelo de Chat Actual" + }, + "restoreLastChatModel": { + "label": "Restaurar el último modelo utilizado para chats anteriores" + }, + "sendNotificationAfterIndexing": { + "label": "Enviar notificación después de terminar el procesamiento de la base de conocimientos" + } }, - "manageModels": { - "title": "Administar de Modelos", - "addBtn": "Agregar Nuevo Modelo", - "columns": { - "name": "Nombre", - "digest": "Resumen", - "modifiedAt": "Modificado", - "size": "Tamaño", - "actions": "Acciones" - }, - "expandedColumns": { - "parentModel": "Modelo Padre", - "format": "Formato", - "family": "Familia", - "parameterSize": "Tamaño de Parametros", - "quantizationLevel": "Nível de Quantización" - }, - "tooltip": { - "delete": "Borrar Modelo", - "repull": "Traer nuevamente el Modelo" - }, - "confirm": { - "delete": "¿Esta seguro que desea borrar este modelos?", - "repull": "¿Esta seguro que desea traer nuevamente este modelo?" - }, - "modal": { - "title": "Traer Nuevo Modelo", - "placeholder": "Ingresar el nombre del modelo", - "pull": "Traer Modelo" - }, - "notification": { - "pullModel": "Trayendo Modelo", - "pullModelDescription": "Trayendo modelo {{modelName}}. Para más detalles, verifique el ícono de la extensión.", - "success": "Exito", - "error": "Error", - "successDescription": "Modelo traido exitosamente", - "successDeleteDescription": "Modelo borrado exitosamente", - "someError": "Hubo un error. Intente nuevamente más tarde" - } + "webSearch": { + "heading": "Manejo de la busqueda Web", + "searchMode": { + "label": "Realizar busquedas Simples en Internet" + }, + "provider": { + "label": "Motor de Busqueda", + "placeholder": "Selecione un motor de busqueda" + }, + "totalSearchResults": { + "label": "Resultados totales de la busqueda", + "placeholder": "Ingresar el total de Resultados de la busqueda" + }, + "visitSpecificWebsite": { + "label": "Visita el sitio web mencionado en el mensaje" + } }, - "managePrompts": { - "title": "Administrar de Prompts", - "addBtn": "Agregar Nuevo Prompt", - "option1": "Normal", - "option2": "RAG", - "questionPrompt": "Prompt de Pregunta", - "columns": { - "title": "Título", - "prompt": "Prompt", - "type": "Tipo de Prompt", - "actions": "Acciones" - }, - "systemPrompt": "Prompt del Sistema", - "quickPrompt": "Prompt Rápido", - "tooltip": { - "delete": "Borrar Prompt", - "edit": "Editar Prompt" - }, - "confirm": { - "delete": "¿Esta seguro que desea borrar este prompt? Esta acción no tiene vuelta a atrás." - }, - "modal": { - "addTitle": "Agregar Nuevo Prompt", - "editTitle": "Editar Prompt" - }, - "form": { - "title": { - "label": "Título", - "placeholder": "Mi Prompt genial", - "required": "Por favor, ingrese un título" - }, - "prompt": { - "label": "Prompt", - "placeholder": "Ingrese un prompt", - "required": "Por favor, ingrese un prompt", - "help": "Puede usar {key} como variable en su prompt." - }, - "isSystem": { - "label": "Es un Prompt del Sistema" - }, - "btnSave": { - "saving": "Agregando un Prompt...", - "save": "Agregar Prompt" - }, - "btnEdit": { - "saving": "Actualizando Prompt...", - "save": "Actualizar Prompt" - } - }, - "notification": { - "addSuccess": "Prompt Agregado", - "addSuccessDesc": "Prompt agregado exitosamente", - "error": "Error", - "someError": "Hubo un error. Intente nuevamente más tarde", - "updatedSuccess": "Prompt Actualizado", - "updatedSuccessDesc": "Prompt actualizado exitosamente", - "deletedSuccess": "Prompt Borrado", - "deletedSuccessDesc": "Prompt borrado exitosamente" - } + "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." + }, + "export": { + "label": "Exportar Histórico del Chat, Base de Conocimiento y Prompts", + "button": "Exportar Datos", + "success": "Exportación exitosa" + }, + "import": { + "label": "Importar Histórico del Chat, Base de Conocimiento y Prompts", + "button": "Importar Datos", + "success": "Importación existosa", + "error": "Error de importación" + } }, - "manageShare": { - "title": "Administrar los recursos compartidos", - "heading": "Configurar URL de Página Compartida", - "form": { - "url": { - "label": "URL de Página compartida", - "placeholder": "Ingresar URL de Página compartida", - "required": "Por favor, ingrese URL de Página compartida", - "help": "Por motivos de privacidad, podes hacer self-host de la página compartida y proveer una URL aqui. Aprende más." - } - }, - "webshare": { - "heading": "Compartir una Web", - "columns": { - "title": "Título", - "url": "URL", - "actions": "Acciones" - }, - "tooltip": { - "delete": "Borrar lo compartido" - }, - "confirm": { - "delete": "¿Esta seguro de desear borrar esta web compartida? Esta acción no tiene vuelta a atrás." - }, - "label": "Administrar páginas compartidas", - "description": "Habilitar o deshabilitar el recurso de páginas compartidas" - }, - "notification": { - "pageShareSuccess": "URL compartida actualizada exitosamente", - "someError": "Hubo un error. Intente nuevamente más tarde", - "webShareDeleteSuccess": "Web compartida borrada exitosamente com sucesso" - } - }, - "ollamaSettings": { - "title": "Configuraciones de Ollama", - "heading": "Configurar Ollama", - "settings": { - "ollamaUrl": { - "label": "URL de Ollama", - "placeholder": "Ingrese la URL de Ollama" - }, - "advanced": { - "label": "Configuración avanzada de URL de Ollama", - "urlRewriteEnabled": { - "label": "Habilitar o Deshabilitar URL Personalizada" - }, - "rewriteUrl": { - "label": "URL Personalizada", - "placeholder": "Ingresar URL Personalizada" - }, - "headers": { - "label": "Encabezados Personalizados", - "add": "Agregar Encabezado", - "key": { - "label": "Clave del Encabezado", - "placeholder": "Autorización" - }, - "value": { - "label": "Valor del Encabezado", - "placeholder": "Token Bearer" - } - }, - "help": "Si tenes problemas de conexión con Ollama en Page Assist, podes configurar una URL de personalizada. Para saber más sobre la configuración, click aqui." - } - } - }, - "manageSearch": { - "title": "Administrar Busqueda Web", - "heading": "Configurar Busqueda Web" - }, - "about": { - "title": "Sobre", - "heading": "Sobre", - "chromeVersion": "Versión de Page Assist", - "ollamaVersion": "Versión de Ollama", - "support": "Podes apoyar el proyecto Page Assist haciendo donaciones o patrocinarnos a través de las seguientes plataformas:", - "koFi": "Apoyar en Ko-fi", - "githubSponsor": "Patrocinarnos en GitHub", - "githubRepo": "Repositorio de GitHub" - }, - "manageKnowledge": { - "title": "Administrar Conocimiento", - "heading": "Configurar Bases de Conocimiento" - }, - "rag": { - "title": "Configuraciones de RAG", - "ragSettings": { - "label": "Configuraciones de RAG", - "model": { - "label": "Modelo de embeddings", - "required": "Por favor, selecione un modelo", - "help": "Es recomendable usar modelos de embeddings como `nomic-embed-text`.", - "placeholder": "Selecione un modelo" - }, - "chunkSize": { - "label": "Tamaño del Chunk", - "placeholder": "Ingresar el tamaño del chunk", - "required": "Por favor, ingrese el tamaño del chunk" - }, - "chunkOverlap": { - "label": "Solapamiento del Chunk", - "placeholder": "Ingrese el solapamiento del chunk", - "required": "Por favor, ingresar el solapamiento del chunk" - } - }, - "prompt": { - "label": "Configurar el Prompt del RAG", - "option1": "Normal", - "option2": "Web", - "alert": "Es obsoleto configurar aquí el prompt del sistema. Por favor, use la sección de Administrar Prompts para agregar o editar prompts. Esta sección se quitará en una versión futura", - "systemPrompt": "Prompt del Sistema", - "systemPromptPlaceholder": "Ingresar el prompt del sistema", - "webSearchPrompt": "Prompt de la busqueda Web", - "webSearchPromptHelp": "No borre `{search_results}` del prompt.", - "webSearchPromptError": "Por favor, ingresar un prompt de busqueda web", - "webSearchPromptPlaceholder": "Ingrese un prompt de busqueda web", - "webSearchFollowUpPrompt": "Prompt de Seguimiento de busqueda Web", - "webSearchFollowUpPromptHelp": "No borre `{chat_history}` y `{question}` del prompt.", - "webSearchFollowUpPromptError": "Por favor, ingrese el prompt de seguimiento de la busqueda web", - "webSearchFollowUpPromptPlaceholder": "Su prompt de seguimiento de busqueda web" - } - }, - "chromeAiSettings": { - "title": "Configuración de IA de Chrome" + "tts": { + "heading": "Configuraciones de Text-to-speech", + "ttsEnabled": { + "label": "Habilitar Texto-a-Voz" + }, + "ttsProvider": { + "label": "Proveedor de Text-to-speech", + "placeholder": "Selecione un proveedor" + }, + "ttsVoice": { + "label": "Voz de Text-to-speech", + "placeholder": "Selecione una voz" + }, + "ssmlEnabled": { + "label": "Habilitar SSML (Speech Synthesis Markup Language)" + } } -} \ No newline at end of file + }, + "manageModels": { + "title": "Administar de Modelos", + "addBtn": "Agregar Nuevo Modelo", + "columns": { + "name": "Nombre", + "digest": "Resumen", + "modifiedAt": "Modificado", + "size": "Tamaño", + "actions": "Acciones" + }, + "expandedColumns": { + "parentModel": "Modelo Padre", + "format": "Formato", + "family": "Familia", + "parameterSize": "Tamaño de Parametros", + "quantizationLevel": "Nível de Quantización" + }, + "tooltip": { + "delete": "Borrar Modelo", + "repull": "Traer nuevamente el Modelo" + }, + "confirm": { + "delete": "¿Esta seguro que desea borrar este modelos?", + "repull": "¿Esta seguro que desea traer nuevamente este modelo?" + }, + "modal": { + "title": "Traer Nuevo Modelo", + "placeholder": "Ingresar el nombre del modelo", + "pull": "Traer Modelo" + }, + "notification": { + "pullModel": "Trayendo Modelo", + "pullModelDescription": "Trayendo modelo {{modelName}}. Para más detalles, verifique el ícono de la extensión.", + "success": "Exito", + "error": "Error", + "successDescription": "Modelo traido exitosamente", + "successDeleteDescription": "Modelo borrado exitosamente", + "someError": "Hubo un error. Intente nuevamente más tarde" + } + }, + "managePrompts": { + "title": "Administrar de Prompts", + "addBtn": "Agregar Nuevo Prompt", + "option1": "Normal", + "option2": "RAG", + "questionPrompt": "Prompt de Pregunta", + "columns": { + "title": "Título", + "prompt": "Prompt", + "type": "Tipo de Prompt", + "actions": "Acciones" + }, + "systemPrompt": "Prompt del Sistema", + "quickPrompt": "Prompt Rápido", + "tooltip": { + "delete": "Borrar Prompt", + "edit": "Editar Prompt" + }, + "confirm": { + "delete": "¿Esta seguro que desea borrar este prompt? Esta acción no tiene vuelta a atrás." + }, + "modal": { + "addTitle": "Agregar Nuevo Prompt", + "editTitle": "Editar Prompt" + }, + "form": { + "title": { + "label": "Título", + "placeholder": "Mi Prompt genial", + "required": "Por favor, ingrese un título" + }, + "prompt": { + "label": "Prompt", + "placeholder": "Ingrese un prompt", + "required": "Por favor, ingrese un prompt", + "help": "Puede usar {key} como variable en su prompt." + }, + "isSystem": { + "label": "Es un Prompt del Sistema" + }, + "btnSave": { + "saving": "Agregando un Prompt...", + "save": "Agregar Prompt" + }, + "btnEdit": { + "saving": "Actualizando Prompt...", + "save": "Actualizar Prompt" + } + }, + "notification": { + "addSuccess": "Prompt Agregado", + "addSuccessDesc": "Prompt agregado exitosamente", + "error": "Error", + "someError": "Hubo un error. Intente nuevamente más tarde", + "updatedSuccess": "Prompt Actualizado", + "updatedSuccessDesc": "Prompt actualizado exitosamente", + "deletedSuccess": "Prompt Borrado", + "deletedSuccessDesc": "Prompt borrado exitosamente" + } + }, + "manageShare": { + "title": "Administrar los recursos compartidos", + "heading": "Configurar URL de Página Compartida", + "form": { + "url": { + "label": "URL de Página compartida", + "placeholder": "Ingresar URL de Página compartida", + "required": "Por favor, ingrese URL de Página compartida", + "help": "Por motivos de privacidad, podes hacer self-host de la página compartida y proveer una URL aqui. Aprende más." + } + }, + "webshare": { + "heading": "Compartir una Web", + "columns": { + "title": "Título", + "url": "URL", + "actions": "Acciones" + }, + "tooltip": { + "delete": "Borrar lo compartido" + }, + "confirm": { + "delete": "¿Esta seguro de desear borrar esta web compartida? Esta acción no tiene vuelta a atrás." + }, + "label": "Administrar páginas compartidas", + "description": "Habilitar o deshabilitar el recurso de páginas compartidas" + }, + "notification": { + "pageShareSuccess": "URL compartida actualizada exitosamente", + "someError": "Hubo un error. Intente nuevamente más tarde", + "webShareDeleteSuccess": "Web compartida borrada exitosamente com sucesso" + } + }, + "ollamaSettings": { + "title": "Configuraciones de Ollama", + "heading": "Configurar Ollama", + "settings": { + "ollamaUrl": { + "label": "URL de Ollama", + "placeholder": "Ingrese la URL de Ollama" + }, + "advanced": { + "label": "Configuración avanzada de URL de Ollama", + "urlRewriteEnabled": { + "label": "Habilitar o Deshabilitar URL Personalizada" + }, + "rewriteUrl": { + "label": "URL Personalizada", + "placeholder": "Ingresar URL Personalizada" + }, + "headers": { + "label": "Encabezados Personalizados", + "add": "Agregar Encabezado", + "key": { + "label": "Clave del Encabezado", + "placeholder": "Autorización" + }, + "value": { + "label": "Valor del Encabezado", + "placeholder": "Token Bearer" + } + }, + "help": "Si tenes problemas de conexión con Ollama en Page Assist, podes configurar una URL de personalizada. Para saber más sobre la configuración, click aqui." + } + } + }, + "manageSearch": { + "title": "Administrar Busqueda Web", + "heading": "Configurar Busqueda Web" + }, + "about": { + "title": "Sobre", + "heading": "Sobre", + "chromeVersion": "Versión de Page Assist", + "ollamaVersion": "Versión de Ollama", + "support": "Podes apoyar el proyecto Page Assist haciendo donaciones o patrocinarnos a través de las seguientes plataformas:", + "koFi": "Apoyar en Ko-fi", + "githubSponsor": "Patrocinarnos en GitHub", + "githubRepo": "Repositorio de GitHub" + }, + "manageKnowledge": { + "title": "Administrar Conocimiento", + "heading": "Configurar Bases de Conocimiento" + }, + "rag": { + "title": "Configuraciones de RAG", + "ragSettings": { + "label": "Configuraciones de RAG", + "model": { + "label": "Modelo de embeddings", + "required": "Por favor, selecione un modelo", + "help": "Es recomendable usar modelos de embeddings como `nomic-embed-text`.", + "placeholder": "Selecione un modelo" + }, + "chunkSize": { + "label": "Tamaño del Chunk", + "placeholder": "Ingresar el tamaño del chunk", + "required": "Por favor, ingrese el tamaño del chunk" + }, + "chunkOverlap": { + "label": "Solapamiento del Chunk", + "placeholder": "Ingrese el solapamiento del chunk", + "required": "Por favor, ingresar el solapamiento del chunk" + } + }, + "prompt": { + "label": "Configurar el Prompt del RAG", + "option1": "Normal", + "option2": "Web", + "alert": "Es obsoleto configurar aquí el prompt del sistema. Por favor, use la sección de Administrar Prompts para agregar o editar prompts. Esta sección se quitará en una versión futura", + "systemPrompt": "Prompt del Sistema", + "systemPromptPlaceholder": "Ingresar el prompt del sistema", + "webSearchPrompt": "Prompt de la busqueda Web", + "webSearchPromptHelp": "No borre `{search_results}` del prompt.", + "webSearchPromptError": "Por favor, ingresar un prompt de busqueda web", + "webSearchPromptPlaceholder": "Ingrese un prompt de busqueda web", + "webSearchFollowUpPrompt": "Prompt de Seguimiento de busqueda Web", + "webSearchFollowUpPromptHelp": "No borre `{chat_history}` y `{question}` del prompt.", + "webSearchFollowUpPromptError": "Por favor, ingrese el prompt de seguimiento de la busqueda web", + "webSearchFollowUpPromptPlaceholder": "Su prompt de seguimiento de busqueda web" + } + }, + "chromeAiSettings": { + "title": "Configuración de IA de Chrome" + } +} diff --git a/src/assets/locale/fr/knowledge.json b/src/assets/locale/fr/knowledge.json index ada9861..aa22b3f 100644 --- a/src/assets/locale/fr/knowledge.json +++ b/src/assets/locale/fr/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "En attente", "finished": "Terminé", - "processing": "Traitement" + "processing": "Traitement", + "failed": "Échoué" }, "addKnowledge": "Ajouter des connaissances", "form": { diff --git a/src/assets/locale/fr/settings.json b/src/assets/locale/fr/settings.json index 97cf952..6af2a68 100644 --- a/src/assets/locale/fr/settings.json +++ b/src/assets/locale/fr/settings.json @@ -1,307 +1,313 @@ { - "generalSettings": { - "title": "Réglages généraux", - "settings": { - "heading": "Paramètres d'interface utilisateur Web", - "speechRecognitionLang": { - "label": "Langue de reconnaissance vocale", - "placeholder": "Sélectionnez une langue" - }, - "language": { - "label": "Langue", - "placeholder": "Sélectionnez une langue" - }, - "darkMode": { - "label": "Change le thème", - "options": { - "light": "Clair", - "dark": "Sombre" - } - }, - "copilotResumeLastChat": { - "label": "Reprendre la dernière conversation lors de l'ouverture du sidepanel (Copilot)" - }, - "hideCurrentChatModelSettings": { - "label": "Masquer les paramètres actuels du modèle de chat" - } - }, - "webSearch": { - "heading": "Gérer la recherche Web", - "searchMode": { - "label": "Effectuer une simple recherche sur Internet" - }, - "provider": { - "label": "Moteur de recherche", - "placeholder": "Sélectionnez un moteur de recherche" - }, - "totalSearchResults": { - "label": "Résultats de la recherche totaux", - "placeholder": "Entrez les résultats de la recherche totaux" - }, - "visitSpecificWebsite": { - "label": "Visitez le site web mentionné dans le message" - } - }, - "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." - }, - "export": { - "label": "Exporter l'historique du chat, la base de connaissances et les invites", - "button": "Exporter des données", - "success": "Succès de l'exportation" - }, - "import": { - "label": "Importer l'historique du chat, la base de connaissances et les invites", - "button": "Importer des données", - "success": "Succès d'importation", - "error": "Erreur d'importation" - } - }, - "tts": { - "heading": "Paramètres de synthèse vocale", - "ttsEnabled": { - "label": "Activer la synthèse vocale" - }, - "ttsProvider": { - "label": "Fournisseur de synthèse vocale", - "placeholder": "Sélectionnez un fournisseur" - }, - "ttsVoice": { - "label": "Voix de synthèse vocale", - "placeholder": "Sélectionnez une voix" - }, - "ssmlEnabled": { - "label": "Activer SSML (langage de balisage de synthèse vocale)" - } + "generalSettings": { + "title": "Réglages généraux", + "settings": { + "heading": "Paramètres d'interface utilisateur Web", + "speechRecognitionLang": { + "label": "Langue de reconnaissance vocale", + "placeholder": "Sélectionnez une langue" + }, + "language": { + "label": "Langue", + "placeholder": "Sélectionnez une langue" + }, + "darkMode": { + "label": "Change le thème", + "options": { + "light": "Clair", + "dark": "Sombre" } + }, + "copilotResumeLastChat": { + "label": "Reprendre la dernière conversation lors de l'ouverture du sidepanel (Copilot)" + }, + "hideCurrentChatModelSettings": { + "label": "Masquer les paramètres actuels du modèle de chat" + }, + "restoreLastChatModel": { + "label": "Restaurer le dernier modèle utilisé pour les conversations précédentes" + }, + "sendNotificationAfterIndexing": { + "label": "Envoyer une notification après avoir terminé le traitement de la base de connaissances" + } }, - "manageModels": { - "title": "Gérer les modèles", - "addBtn": "Ajouter un nouveau modèle", - "columns": { - "name": "Nom", - "digest": "Digérer", - "modifiedAt": "Modifié à", - "size": "Taille", - "actions": "Actions" - }, - "expandedColumns": { - "parentModel": "Modèle parent", - "format": "Format", - "family": "Famille", - "parameterSize": "Taille du paramètre", - "quantizationLevel": "Niveau de quantification" - }, - "tooltip": { - "delete": "Supprimer le modèle", - "repull": "Modèle de ré-échoue" - }, - "confirm": { - "delete": "Êtes-vous sûr de vouloir supprimer ce modèle?", - "repull": "Êtes-vous sûr de vouloir rétracter ce modèle?" - }, - "modal": { - "title": "Ajouter un nouveau modèle", - "placeholder": "Entrez le nom du modèle", - "pull": "Modèle de traction" - }, - "notification": { - "pullModel": "Modèle de traction", - "pullModelDescription": "Tirling {{ModelName}} modèle. Pour plus de détails, vérifiez l'icône d'extension.", - "success": "Succès", - "error": "Erreur", - "successDescription": "A réussi à tirer le modèle", - "successDeleteDescription": "Supprimé avec succès le modèle", - "someError": "Quelque chose s'est mal passé.Veuillez réessayer plus tard" - } + "webSearch": { + "heading": "Gérer la recherche Web", + "searchMode": { + "label": "Effectuer une simple recherche sur Internet" + }, + "provider": { + "label": "Moteur de recherche", + "placeholder": "Sélectionnez un moteur de recherche" + }, + "totalSearchResults": { + "label": "Résultats de la recherche totaux", + "placeholder": "Entrez les résultats de la recherche totaux" + }, + "visitSpecificWebsite": { + "label": "Visitez le site web mentionné dans le message" + } }, - "managePrompts": { - "title": "Gérer les prompts", - "addBtn": "Ajouter un nouveau prompt", - "option1": "Normale", - "option2": "RAG", - "questionPrompt": "Prompt de question", - "columns": { - "title": "Titre", - "prompt": "Prompt", - "type": "Type de prompt", - "actions": "Actions" - }, - "systemPrompt": "Prompt système", - "quickPrompt": "Prompt rapide", - "tooltip": { - "delete": "Supprimer le prompt", - "edit": "Modifier le prompt" - }, - "confirm": { - "delete": "Êtes-vous sûr de vouloir supprimer cette invite ? Cette action ne peut pas être annulée." - }, - "modal": { - "addTitle": "Ajouter un nouveau prompt", - "editTitle": "Modifier le prompt" - }, - "form": { - "title": { - "label": "Titre", - "placeholder": "Mon super prompt", - "required": "Veuillez saisir un titre" - }, - "prompt": { - "label": "Prompt", - "placeholder": "Entrer Prompt", - "required": "Veuillez entrer un prompt", - "help": "Vous pouvez utiliser {key} comme variable dans votre prompt." - }, - "isSystem": { - "label": "Est un prompt système" - }, - "btnSave": { - "saving": "Ajout de Prompt...", - "save": "Ajouter un prompt" - }, - "btnEdit": { - "saving": "Mise à jour du Prompt...", - "save": "Modifier le prompt" - } - }, - "notification": { - "addSuccess": "Prompt ajouté", - "addSuccessDesc": "Le prompt a été ajoutée avec succès", - "error": "Erreur", - "someError": "Quelque chose s'est mal passé. Veuillez réessayer plus tard", - "updatedSuccess": "Prompt mise à jour", - "updatedSuccessDesc": "Le prompt a été mis à jour avec succès", - "deletedSuccess": "Prompt supprimé", - "deletedSuccessDesc": "Le prompt a été supprimé avec succès" - } + "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." + }, + "export": { + "label": "Exporter l'historique du chat, la base de connaissances et les invites", + "button": "Exporter des données", + "success": "Succès de l'exportation" + }, + "import": { + "label": "Importer l'historique du chat, la base de connaissances et les invites", + "button": "Importer des données", + "success": "Succès d'importation", + "error": "Erreur d'importation" + } }, - "manageShare": { - "title": "Gérer le partage", - "heading": "Configurer l'URL de partage de la page", - "form": { - "url": { - "label": "URL de partage de page", - "placeholder": "Entrez l'URL de partage de la page", - "required": "Veuillez saisir URL de partage de votre page!", - "help": "Pour des raisons de confidentialité, vous pouvez auto-héberger le partage de la page et fournir l'URL ici.En savoir plus." - } - }, - "webshare": { - "heading": "Partage Web", - "columns": { - "title": "Titre", - "url": "URL", - "actions": "Actions" - }, - "tooltip": { - "delete": "Supprimer le partage" - }, - "confirm": { - "delete": "Êtes-vous sûr de vouloir supprimer ce partage ? Cette action ne peut pas être annulée." - }, - "label": "Gérer le partage de pages", - "description": "Activer ou désactiver la fonction de partage de page" - }, - "notification": { - "pageShareSuccess": "URL de partage de page mise à jour avec succès", - "someError": "Quelque chose a mal tourné. Veuillez réessayer plus tard", - "webShareDeleteSuccess": "Partage Web supprimé avec succès" - } - }, - "ollamaSettings": { - "title": "Réglages de Ollama", - "heading": "Configurer Ollama", - "settings": { - "ollamaUrl": { - "label": "Url de Ollama", - "placeholder": "Entrer l'url de Ollama" - }, - "advanced": { - "label": "Configuration avancée de l'URL de Ollama", - "urlRewriteEnabled": { - "label": "Activer ou désactiver l'URL d'origine personnalisée" - }, - "rewriteUrl": { - "label": "URL d'origine personnalisée", - "placeholder": "Entrez l'URL d'origine personnalisée" - }, - "headers": { - "label": "En-têtes Personnalisés", - "add": "Ajouter En-tête", - "key": { - "label": "Clé de l'En-tête", - "placeholder": "Autorisation" - }, - "value": { - "label": "Valeur de l'En-tête", - "placeholder": "Jeton Bearer" - } - }, - "help": "Si vous avez des problèmes de connexion avec OLLAMA sur Page Assist, vous pouvez configurer une URL d'origine personnalisée. Pour en savoir plus sur la configuration, cliquez ici." - } - } - }, - "manageSearch": { - "title": "Gérer la recherche Web", - "heading": "Configurer la recherche Web" - }, - "about": { - "title": "À propos", - "heading": "À propos", - "chromeVersion": "Version de Page Assist", - "ollamaVersion": "Version de Ollama", - "support": "Vous pouvez supporter le projet Page Assist en donnant ou parrainant via les plateformes suivantes:", - "koFi": "Supporter sur ko-fi", - "githubSponsor": "Sponsoriser sur github", - "githubRepo": "Référentiel GitHub" - }, - "manageKnowledge": { - "title": "Gérer les connaissances", - "heading": "Configurer la base de connaissances" - }, - "rag": { - "title": "Paramètres de RAG", - "ragSettings": { - "label": "Paramètres de RAG", - "model": { - "label": "Modèle d'embedding", - "required": "Veuillez sélectionner un modèle", - "help": "Fortement recommandé d'utiliser des modèles d'embedding comme «momic-embed-text».", - "placeholder": "Sélectionnez un modèle" - }, - "chunkSize": { - "label": "Taille", - "placeholder": "Entrez la taille du morceau", - "required": "Veuillez saisir une taille" - }, - "chunkOverlap": { - "label": "Chevauchement", - "placeholder": "Entrez le chevauchement des morceaux", - "required": "Veuillez saisir un chevauchement" - } - }, - "prompt": { - "label": "Configure RAG Prompt", - "option1": "Normal", - "option2": "Web", - "alert": "La configuration du prompt système ici est déconseillée. Veuillez utiliser la section Gérer les prompts pour ajouter...", - "systemPrompt": "Prompt système", - "systemPromptPlaceholder": "Entrez le prompt système", - "webSearchPrompt": "Prompt de recherche Web", - "webSearchPromptHelp": "Ne supprimez pas `{search_results}` du prompt.", - "webSearchPromptError": "Veuillez saisir un prompt de recherche Web", - "webSearchPromptPlaceholder": "Entrez le prompt de recherche Web", - "webSearchFollowUpPrompt": "Prompt de suivi de recherche Web", - "webSearchFollowUpPromptHelp": "Ne supprimez pas `{chat_history}` et `{question}` du prompt.", - "webSearchFollowUpPromptError": "Veuillez saisir votre prompt de suivi de recherche Web!", - "webSearchFollowUpPromptPlaceholder": "Votre prompt de suivi de recherche Web" - } - }, - "chromeAiSettings": { - "title": "Paramètres IA de Chrome" + "tts": { + "heading": "Paramètres de synthèse vocale", + "ttsEnabled": { + "label": "Activer la synthèse vocale" + }, + "ttsProvider": { + "label": "Fournisseur de synthèse vocale", + "placeholder": "Sélectionnez un fournisseur" + }, + "ttsVoice": { + "label": "Voix de synthèse vocale", + "placeholder": "Sélectionnez une voix" + }, + "ssmlEnabled": { + "label": "Activer SSML (langage de balisage de synthèse vocale)" + } } -} \ No newline at end of file + }, + "manageModels": { + "title": "Gérer les modèles", + "addBtn": "Ajouter un nouveau modèle", + "columns": { + "name": "Nom", + "digest": "Digérer", + "modifiedAt": "Modifié à", + "size": "Taille", + "actions": "Actions" + }, + "expandedColumns": { + "parentModel": "Modèle parent", + "format": "Format", + "family": "Famille", + "parameterSize": "Taille du paramètre", + "quantizationLevel": "Niveau de quantification" + }, + "tooltip": { + "delete": "Supprimer le modèle", + "repull": "Modèle de ré-échoue" + }, + "confirm": { + "delete": "Êtes-vous sûr de vouloir supprimer ce modèle?", + "repull": "Êtes-vous sûr de vouloir rétracter ce modèle?" + }, + "modal": { + "title": "Ajouter un nouveau modèle", + "placeholder": "Entrez le nom du modèle", + "pull": "Modèle de traction" + }, + "notification": { + "pullModel": "Modèle de traction", + "pullModelDescription": "Tirling {{ModelName}} modèle. Pour plus de détails, vérifiez l'icône d'extension.", + "success": "Succès", + "error": "Erreur", + "successDescription": "A réussi à tirer le modèle", + "successDeleteDescription": "Supprimé avec succès le modèle", + "someError": "Quelque chose s'est mal passé.Veuillez réessayer plus tard" + } + }, + "managePrompts": { + "title": "Gérer les prompts", + "addBtn": "Ajouter un nouveau prompt", + "option1": "Normale", + "option2": "RAG", + "questionPrompt": "Prompt de question", + "columns": { + "title": "Titre", + "prompt": "Prompt", + "type": "Type de prompt", + "actions": "Actions" + }, + "systemPrompt": "Prompt système", + "quickPrompt": "Prompt rapide", + "tooltip": { + "delete": "Supprimer le prompt", + "edit": "Modifier le prompt" + }, + "confirm": { + "delete": "Êtes-vous sûr de vouloir supprimer cette invite ? Cette action ne peut pas être annulée." + }, + "modal": { + "addTitle": "Ajouter un nouveau prompt", + "editTitle": "Modifier le prompt" + }, + "form": { + "title": { + "label": "Titre", + "placeholder": "Mon super prompt", + "required": "Veuillez saisir un titre" + }, + "prompt": { + "label": "Prompt", + "placeholder": "Entrer Prompt", + "required": "Veuillez entrer un prompt", + "help": "Vous pouvez utiliser {key} comme variable dans votre prompt." + }, + "isSystem": { + "label": "Est un prompt système" + }, + "btnSave": { + "saving": "Ajout de Prompt...", + "save": "Ajouter un prompt" + }, + "btnEdit": { + "saving": "Mise à jour du Prompt...", + "save": "Modifier le prompt" + } + }, + "notification": { + "addSuccess": "Prompt ajouté", + "addSuccessDesc": "Le prompt a été ajoutée avec succès", + "error": "Erreur", + "someError": "Quelque chose s'est mal passé. Veuillez réessayer plus tard", + "updatedSuccess": "Prompt mise à jour", + "updatedSuccessDesc": "Le prompt a été mis à jour avec succès", + "deletedSuccess": "Prompt supprimé", + "deletedSuccessDesc": "Le prompt a été supprimé avec succès" + } + }, + "manageShare": { + "title": "Gérer le partage", + "heading": "Configurer l'URL de partage de la page", + "form": { + "url": { + "label": "URL de partage de page", + "placeholder": "Entrez l'URL de partage de la page", + "required": "Veuillez saisir URL de partage de votre page!", + "help": "Pour des raisons de confidentialité, vous pouvez auto-héberger le partage de la page et fournir l'URL ici.En savoir plus." + } + }, + "webshare": { + "heading": "Partage Web", + "columns": { + "title": "Titre", + "url": "URL", + "actions": "Actions" + }, + "tooltip": { + "delete": "Supprimer le partage" + }, + "confirm": { + "delete": "Êtes-vous sûr de vouloir supprimer ce partage ? Cette action ne peut pas être annulée." + }, + "label": "Gérer le partage de pages", + "description": "Activer ou désactiver la fonction de partage de page" + }, + "notification": { + "pageShareSuccess": "URL de partage de page mise à jour avec succès", + "someError": "Quelque chose a mal tourné. Veuillez réessayer plus tard", + "webShareDeleteSuccess": "Partage Web supprimé avec succès" + } + }, + "ollamaSettings": { + "title": "Réglages de Ollama", + "heading": "Configurer Ollama", + "settings": { + "ollamaUrl": { + "label": "Url de Ollama", + "placeholder": "Entrer l'url de Ollama" + }, + "advanced": { + "label": "Configuration avancée de l'URL de Ollama", + "urlRewriteEnabled": { + "label": "Activer ou désactiver l'URL d'origine personnalisée" + }, + "rewriteUrl": { + "label": "URL d'origine personnalisée", + "placeholder": "Entrez l'URL d'origine personnalisée" + }, + "headers": { + "label": "En-têtes Personnalisés", + "add": "Ajouter En-tête", + "key": { + "label": "Clé de l'En-tête", + "placeholder": "Autorisation" + }, + "value": { + "label": "Valeur de l'En-tête", + "placeholder": "Jeton Bearer" + } + }, + "help": "Si vous avez des problèmes de connexion avec OLLAMA sur Page Assist, vous pouvez configurer une URL d'origine personnalisée. Pour en savoir plus sur la configuration, cliquez ici." + } + } + }, + "manageSearch": { + "title": "Gérer la recherche Web", + "heading": "Configurer la recherche Web" + }, + "about": { + "title": "À propos", + "heading": "À propos", + "chromeVersion": "Version de Page Assist", + "ollamaVersion": "Version de Ollama", + "support": "Vous pouvez supporter le projet Page Assist en donnant ou parrainant via les plateformes suivantes:", + "koFi": "Supporter sur ko-fi", + "githubSponsor": "Sponsoriser sur github", + "githubRepo": "Référentiel GitHub" + }, + "manageKnowledge": { + "title": "Gérer les connaissances", + "heading": "Configurer la base de connaissances" + }, + "rag": { + "title": "Paramètres de RAG", + "ragSettings": { + "label": "Paramètres de RAG", + "model": { + "label": "Modèle d'embedding", + "required": "Veuillez sélectionner un modèle", + "help": "Fortement recommandé d'utiliser des modèles d'embedding comme «momic-embed-text».", + "placeholder": "Sélectionnez un modèle" + }, + "chunkSize": { + "label": "Taille", + "placeholder": "Entrez la taille du morceau", + "required": "Veuillez saisir une taille" + }, + "chunkOverlap": { + "label": "Chevauchement", + "placeholder": "Entrez le chevauchement des morceaux", + "required": "Veuillez saisir un chevauchement" + } + }, + "prompt": { + "label": "Configure RAG Prompt", + "option1": "Normal", + "option2": "Web", + "alert": "La configuration du prompt système ici est déconseillée. Veuillez utiliser la section Gérer les prompts pour ajouter...", + "systemPrompt": "Prompt système", + "systemPromptPlaceholder": "Entrez le prompt système", + "webSearchPrompt": "Prompt de recherche Web", + "webSearchPromptHelp": "Ne supprimez pas `{search_results}` du prompt.", + "webSearchPromptError": "Veuillez saisir un prompt de recherche Web", + "webSearchPromptPlaceholder": "Entrez le prompt de recherche Web", + "webSearchFollowUpPrompt": "Prompt de suivi de recherche Web", + "webSearchFollowUpPromptHelp": "Ne supprimez pas `{chat_history}` et `{question}` du prompt.", + "webSearchFollowUpPromptError": "Veuillez saisir votre prompt de suivi de recherche Web!", + "webSearchFollowUpPromptPlaceholder": "Votre prompt de suivi de recherche Web" + } + }, + "chromeAiSettings": { + "title": "Paramètres IA de Chrome" + } +} diff --git a/src/assets/locale/it/knowledge.json b/src/assets/locale/it/knowledge.json index 69fabc1..0f01462 100644 --- a/src/assets/locale/it/knowledge.json +++ b/src/assets/locale/it/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "In attesa", "finished": "Completato", - "processing": "In corso" + "processing": "In corso", + "failed": "Fallito" }, "addKnowledge": "Aggiungi Knowledge Base", "form": { diff --git a/src/assets/locale/it/settings.json b/src/assets/locale/it/settings.json index 3af9bae..31aed04 100644 --- a/src/assets/locale/it/settings.json +++ b/src/assets/locale/it/settings.json @@ -23,6 +23,12 @@ }, "hideCurrentChatModelSettings": { "label": "Nascondi le impostazioni correnti del modello Chat" + }, + "restoreLastChatModel": { + "label": "Ripristina l'ultimo modello utilizzato per le chat precedenti" + }, + "sendNotificationAfterIndexing": { + "label": "Inviare notifica dopo aver terminato l'elaborazione della base di conoscenza" } }, "webSearch": { diff --git a/src/assets/locale/ja-JP/knowledge.json b/src/assets/locale/ja-JP/knowledge.json index 1efe898..866631c 100644 --- a/src/assets/locale/ja-JP/knowledge.json +++ b/src/assets/locale/ja-JP/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "保留中", "finished": "完了", - "processing": "処理中" + "processing": "処理中", + "failed": "失敗" }, "addKnowledge": "知識を追加", "form": { diff --git a/src/assets/locale/ja-JP/settings.json b/src/assets/locale/ja-JP/settings.json index de5e20b..f11105b 100644 --- a/src/assets/locale/ja-JP/settings.json +++ b/src/assets/locale/ja-JP/settings.json @@ -26,6 +26,12 @@ }, "hideCurrentChatModelSettings": { "label": "現在のチャットモデル設定を非表示" + }, + "restoreLastChatModel": { + "label": "以前のチャットで最後に使用したモデルを復元する" + }, + "sendNotificationAfterIndexing": { + "label": "ナレッジベースの処理完了後に通知を送信" } }, "webSearch": { @@ -306,5 +312,5 @@ }, "chromeAiSettings": { "title": "Chrome AI設定" -} + } } diff --git a/src/assets/locale/ml/knowledge.json b/src/assets/locale/ml/knowledge.json index fc92e27..41d8267 100644 --- a/src/assets/locale/ml/knowledge.json +++ b/src/assets/locale/ml/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "തീരുമാനിക്കാനുണ്ട്", "finished": "പൂർത്തീകരിച്ചു", - "processing": "പ്രോസസ്സിംഗ്" + "processing": "പ്രോസസ്സിംഗ്", + "failed": "പരാജയപ്പെട്ടു" }, "addKnowledge": "വിജ്ഞാനം ചേര്‍ക്കുക", "form": { diff --git a/src/assets/locale/ml/settings.json b/src/assets/locale/ml/settings.json index 5e6c1a6..d46f628 100644 --- a/src/assets/locale/ml/settings.json +++ b/src/assets/locale/ml/settings.json @@ -26,6 +26,12 @@ }, "hideCurrentChatModelSettings": { "label": "നിലവിലുള്ള ചാറ്റ് മോഡൽ ക്രമീകരണങ്ങൾ മറയ്ക്കുക" + }, + "restoreLastChatModel": { + "label": "മുൻപത്തെ ചാറ്റുകൾക്കായി അവസാനം ഉപയോഗിച്ച മോഡൽ പുനഃസ്ഥാപിക്കുക" + }, + "sendNotificationAfterIndexing": { + "label": "അറിവ് ശേഖരം പ്രോസസ്സ് ചെയ്ത് കഴിഞ്ഞതിന് ശേഷം അറിയിപ്പ് അയയ്ക്കുക" } }, "webSearch": { diff --git a/src/assets/locale/pt-BR/knowledge.json b/src/assets/locale/pt-BR/knowledge.json index 8c9047a..7d2ebcd 100644 --- a/src/assets/locale/pt-BR/knowledge.json +++ b/src/assets/locale/pt-BR/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "Pendente", "finished": "Concluído", - "processing": "Processando" + "processing": "Processando", + "failed": "Falhou" }, "addKnowledge": "Adicionar Conhecimento", "form": { diff --git a/src/assets/locale/pt-BR/settings.json b/src/assets/locale/pt-BR/settings.json index 611e00c..f396d0a 100644 --- a/src/assets/locale/pt-BR/settings.json +++ b/src/assets/locale/pt-BR/settings.json @@ -23,6 +23,12 @@ }, "hideCurrentChatModelSettings": { "label": "Ocultar as Configurações Atuais do Modelo de Chat" + }, + "restoreLastChatModel": { + "label": "Restaurar o último modelo usado para conversas anteriores" + }, + "sendNotificationAfterIndexing": { + "label": "Enviar notificação após concluir o processamento da base de conhecimento" } }, "webSearch": { @@ -304,4 +310,4 @@ "chromeAiSettings": { "title": "Configurações do Chrome AI" } -} \ No newline at end of file +} diff --git a/src/assets/locale/ru/knowledge.json b/src/assets/locale/ru/knowledge.json index 0a8c740..e0689c0 100644 --- a/src/assets/locale/ru/knowledge.json +++ b/src/assets/locale/ru/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "Ожидание", "finished": "Завершено", - "processing": "Обработка" + "processing": "Обработка", + "failed": "Не удалось" }, "addKnowledge": "Добавить знание", "form": { diff --git a/src/assets/locale/ru/settings.json b/src/assets/locale/ru/settings.json index 48ee2e5..bf85524 100644 --- a/src/assets/locale/ru/settings.json +++ b/src/assets/locale/ru/settings.json @@ -23,6 +23,12 @@ }, "hideCurrentChatModelSettings": { "label": "Скрыть текущие настройки модели чата" + }, + "restoreLastChatModel": { + "label": "Восстановить последнюю использованную модель для предыдущих чатов" + }, + "sendNotificationAfterIndexing": { + "label": "Отправить уведомление после завершения обработки базы знаний" } }, "webSearch": { @@ -304,5 +310,5 @@ }, "chromeAiSettings": { "title": "Настройки ИИ Chrome" -} + } } diff --git a/src/assets/locale/zh/knowledge.json b/src/assets/locale/zh/knowledge.json index 14061f4..fcbfdee 100644 --- a/src/assets/locale/zh/knowledge.json +++ b/src/assets/locale/zh/knowledge.json @@ -20,7 +20,8 @@ "status": { "pending": "待定", "finished": "已完成", - "processing": "处理中" + "processing": "处理中", + "failed": "失败" }, "addKnowledge": "添加知识", "form": { diff --git a/src/assets/locale/zh/settings.json b/src/assets/locale/zh/settings.json index 52e3408..7b93060 100644 --- a/src/assets/locale/zh/settings.json +++ b/src/assets/locale/zh/settings.json @@ -26,6 +26,12 @@ }, "hideCurrentChatModelSettings": { "label": "隐藏当前聊天模型设置" + }, + "restoreLastChatModel": { + "label": "恢复上次用于之前聊天的模型" + }, + "sendNotificationAfterIndexing": { + "label": "完成知识库处理后发送通知" } }, "webSearch": { diff --git a/src/assets/tailwind.css b/src/assets/tailwind.css index e6703c6..ee4b772 100644 --- a/src/assets/tailwind.css +++ b/src/assets/tailwind.css @@ -65,3 +65,63 @@ animation: gradient-border 3s infinite; border-radius: 10px; } + +/* Hide scrollbar by default */ +.custom-scrollbar { + scrollbar-width: none; + -ms-overflow-style: none; +} + +.custom-scrollbar::-webkit-scrollbar { + display: none; +} + +/* Show scrollbar on hover */ +.custom-scrollbar:hover { + scrollbar-width: thin; + -ms-overflow-style: auto; +} + +.custom-scrollbar:hover::-webkit-scrollbar { + display: block; + width: 8px; +} + +/* Custom scrollbar styles for light theme */ +.custom-scrollbar:hover::-webkit-scrollbar-track { + @apply bg-gray-50; + border-radius: 4px; +} + +.custom-scrollbar:hover::-webkit-scrollbar-thumb { + @apply bg-gray-300; + border-radius: 4px; + transition: background 0.2s ease; +} + +.custom-scrollbar:hover::-webkit-scrollbar-thumb:hover { + @apply bg-gray-400; +} + +/* Custom scrollbar styles for dark theme */ +.dark .custom-scrollbar:hover::-webkit-scrollbar-track { + background-color: #262626; +} + +.dark .custom-scrollbar:hover::-webkit-scrollbar-thumb { + background-color: #404040; +} + +.dark .custom-scrollbar:hover::-webkit-scrollbar-thumb:hover { + background-color: #525252; +} + +/* For Firefox */ +.custom-scrollbar { + scrollbar-color: theme('colors.gray.300') theme('colors.gray.50'); + scrollbar-width: thin; +} + +.dark .custom-scrollbar { + scrollbar-color: #404040 #262626; +} diff --git a/src/components/Option/Knowledge/index.tsx b/src/components/Option/Knowledge/index.tsx index 8d5f28a..f1ad058 100644 --- a/src/components/Option/Knowledge/index.tsx +++ b/src/components/Option/Knowledge/index.tsx @@ -37,8 +37,9 @@ export const KnowledgeSettings = () => { const statusColor = { finished: "green", - processing: "blue", - pending: "gray" + processing: "yellow", + pending: "gray", + failed: "red" } return ( diff --git a/src/components/Option/Playground/Playground.tsx b/src/components/Option/Playground/Playground.tsx index a18b258..bc52b59 100644 --- a/src/components/Option/Playground/Playground.tsx +++ b/src/components/Option/Playground/Playground.tsx @@ -78,6 +78,7 @@ export const Playground = () => { dropState === "dragging" ? "bg-gray-100 dark:bg-gray-800 z-10" : "" } bg-white dark:bg-[#171717]`}> +
diff --git a/src/components/Option/Playground/PlaygroundChat.tsx b/src/components/Option/Playground/PlaygroundChat.tsx index c8e90da..e34c594 100644 --- a/src/components/Option/Playground/PlaygroundChat.tsx +++ b/src/components/Option/Playground/PlaygroundChat.tsx @@ -3,6 +3,8 @@ import { useMessageOption } from "~/hooks/useMessageOption" import { PlaygroundEmpty } from "./PlaygroundEmpty" import { PlaygroundMessage } from "~/components/Common/Playground/Message" import { MessageSourcePopup } from "@/components/Common/Playground/MessageSourcePopup" +import { useSmartScroll } from "~/hooks/useSmartScroll" +import { ChevronDown } from "lucide-react" export const PlaygroundChat = () => { const { @@ -13,24 +15,24 @@ export const PlaygroundChat = () => { editMessage, ttsEnabled } = useMessageOption() - const divRef = React.useRef(null) const [isSourceOpen, setIsSourceOpen] = React.useState(false) const [source, setSource] = React.useState(null) - React.useEffect(() => { - if (divRef.current) { - divRef.current.scrollIntoView({ behavior: "smooth" }) - } - }) + + const { containerRef, isAtBottom, scrollToBottom } = useSmartScroll( + messages, + streaming + ) + return ( <> - {" "} -
+
{messages.length === 0 && (
)} - {/* {messages.length > 0 &&
} */} {messages.map((message, index) => ( { /> ))} {messages.length > 0 && ( -
+
)} -
+ {!isAtBottom && ( +
+ +
+ )} { false ) + const [restoreLastChatModel, setRestoreLastChatModel] = useStorage( + "restoreLastChatModel", + false + ) + const [hideCurrentChatModelSettings, setHideCurrentChatModelSettings] = useStorage("hideCurrentChatModelSettings", false) + const [sendNotificationAfterIndexing, setSendNotificationAfterIndexing] = + useStorage("sendNotificationAfterIndexing", false) + const queryClient = useQueryClient() const { mode, toggleDarkMode } = useDarkMode() @@ -107,6 +115,32 @@ export const GeneralSettings = () => { onChange={(checked) => setHideCurrentChatModelSettings(checked)} />
+
+
+ + {t("generalSettings.settings.restoreLastChatModel.label")} + +
+ + setRestoreLastChatModel(checked)} + /> +
+ +
+
+ + {t("generalSettings.settings.sendNotificationAfterIndexing.label")} + +
+ + +
+
{t("generalSettings.settings.darkMode.label")} diff --git a/src/components/Option/Sidebar.tsx b/src/components/Option/Sidebar.tsx index e18f567..9535360 100644 --- a/src/components/Option/Sidebar.tsx +++ b/src/components/Option/Sidebar.tsx @@ -11,14 +11,24 @@ import { useMessageOption } from "~/hooks/useMessageOption" import { PencilIcon, Trash2 } from "lucide-react" import { useNavigate } from "react-router-dom" import { useTranslation } from "react-i18next" +import { + getLastUsedChatModel, + lastUsedChatModelEnabled +} from "@/services/model-settings" type Props = { onClose: () => void } export const Sidebar = ({ onClose }: Props) => { - const { setMessages, setHistory, setHistoryId, historyId, clearChat } = - useMessageOption() + const { + setMessages, + setHistory, + setHistoryId, + historyId, + clearChat, + setSelectedModel + } = useMessageOption() const { t } = useTranslation(["option", "common"]) const client = useQueryClient() const navigate = useNavigate() @@ -88,6 +98,13 @@ export const Sidebar = ({ onClose }: Props) => { setHistoryId(chat.id) setHistory(formatToChatHistory(history)) setMessages(formatToMessage(history)) + const isLastUsedChatModel = await lastUsedChatModelEnabled() + if (isLastUsedChatModel) { + const currentChatModel = await getLastUsedChatModel(chat.id) + if (currentChatModel) { + setSelectedModel(currentChatModel) + } + } navigate("/") onClose() }}> diff --git a/src/entries/background.ts b/src/entries/background.ts index 91c71a7..b238b9a 100644 --- a/src/entries/background.ts +++ b/src/entries/background.ts @@ -1,6 +1,7 @@ import { getOllamaURL, isOllamaRunning } from "../services/ollama" import { browser } from "wxt/browser" import { setBadgeBackgroundColor, setBadgeText, setTitle } from "@/utils/action" + const progressHuman = (completed: number, total: number) => { return ((completed / total) * 100).toFixed(0) + "%" } @@ -75,11 +76,12 @@ const streamDownload = async (url: string, model: string) => { clearBadge() }, 5000) } + export default defineBackground({ main() { browser.runtime.onMessage.addListener(async (message) => { if (message.type === "sidepanel") { - browser.sidebarAction.open() + await browser.sidebarAction.open() } else if (message.type === "pull_model") { const ollamaURL = await getOllamaURL() @@ -100,7 +102,7 @@ export default defineBackground({ if (import.meta.env.BROWSER === "chrome") { chrome.action.onClicked.addListener((tab) => { - browser.tabs.create({ url: browser.runtime.getURL("/options.html") }) + chrome.tabs.create({ url: chrome.runtime.getURL("/options.html") }) }) } else { browser.browserAction.onClicked.addListener((tab) => { @@ -109,23 +111,31 @@ export default defineBackground({ }) } + const contextMenuTitle = { + webUi: browser.i18n.getMessage("openOptionToChat"), + sidePanel: browser.i18n.getMessage("openSidePanelToChat") + } + + const contextMenuId = { + webUi: "open-web-ui-pa", + sidePanel: "open-side-panel-pa" + } + browser.contextMenus.create({ - id: "open-side-panel-pa", - title: browser.i18n.getMessage("openSidePanelToChat"), + id: contextMenuId["sidePanel"], + title: contextMenuTitle["sidePanel"], contexts: ["all"] }) if (import.meta.env.BROWSER === "chrome") { browser.contextMenus.onClicked.addListener((info, tab) => { if (info.menuItemId === "open-side-panel-pa") { - chrome.tabs.query( - { active: true, currentWindow: true }, - async (tabs) => { - const tab = tabs[0] - chrome.sidePanel.open({ - tabId: tab.id! - }) - } - ) + chrome.sidePanel.open({ + tabId: tab.id! + }) + } else if (info.menuItemId === "open-web-ui-pa") { + browser.tabs.create({ + url: browser.runtime.getURL("/options.html") + }) } }) @@ -152,6 +162,10 @@ export default defineBackground({ browser.contextMenus.onClicked.addListener((info, tab) => { if (info.menuItemId === "open-side-panel-pa") { browser.sidebarAction.toggle() + } else if (info.menuItemId === "open-web-ui-pa") { + browser.tabs.create({ + url: browser.runtime.getURL("/options.html") + }) } }) diff --git a/src/hooks/chat-helper/index.ts b/src/hooks/chat-helper/index.ts index 73f8494..f7b690f 100644 --- a/src/hooks/chat-helper/index.ts +++ b/src/hooks/chat-helper/index.ts @@ -1,4 +1,5 @@ import { saveHistory, saveMessage } from "@/db" +import { setLastUsedChatModel } from "@/services/model-settings" import { ChatHistory } from "@/store/option" export const saveMessageOnError = async ({ @@ -23,7 +24,7 @@ export const saveMessageOnError = async ({ historyId: string | null selectedModel: string setHistoryId: (historyId: string) => void - isRegenerating: boolean, + isRegenerating: boolean message_source?: "copilot" | "web-ui" }) => { if ( @@ -66,6 +67,7 @@ export const saveMessageOnError = async ({ [], 2 ) + await setLastUsedChatModel(historyId, selectedModel) } else { const newHistoryId = await saveHistory(userMessage, false, message_source) if (!isRegenerating) { @@ -89,6 +91,7 @@ export const saveMessageOnError = async ({ 2 ) setHistoryId(newHistoryId.id) + await setLastUsedChatModel(newHistoryId.id, selectedModel) } return true @@ -115,7 +118,7 @@ export const saveMessageOnSuccess = async ({ message: string image: string fullText: string - source: any[], + source: any[] message_source?: "copilot" | "web-ui" }) => { if (historyId) { @@ -139,6 +142,7 @@ export const saveMessageOnSuccess = async ({ source, 2 ) + await setLastUsedChatModel(historyId, selectedModel!) } else { const newHistoryId = await saveHistory(message, false, message_source) await saveMessage( @@ -160,5 +164,6 @@ export const saveMessageOnSuccess = async ({ 2 ) setHistoryId(newHistoryId.id) + await setLastUsedChatModel(newHistoryId.id, selectedModel!) } } diff --git a/src/hooks/useScrollAnchor.tsx b/src/hooks/useScrollAnchor.tsx deleted file mode 100644 index c2d72a2..0000000 --- a/src/hooks/useScrollAnchor.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { useCallback, useEffect, useRef, useState } from "react" -import { useMessageOption } from "./useMessageOption" - -export const useScrollAnchor = () => { - const { isProcessing, messages } = useMessageOption() - - const [isAtTop, setIsAtTop] = useState(false) - const [isAtBottom, setIsAtBottom] = useState(true) - const [userScrolled, setUserScrolled] = useState(false) - const [isOverflowing, setIsOverflowing] = useState(false) - - const messagesStartRef = useRef(null) - const messagesEndRef = useRef(null) - const containerRef = useRef(null) - const isAutoScrolling = useRef(false) - - console.log(`isAtTop: ${isAtTop}, isAtBottom: ${isAtBottom}, userScrolled: ${userScrolled}, isOverflowing: ${isOverflowing}`) - - useEffect(() => { - if (!isProcessing && userScrolled) { - console.log("userScrolled") - setUserScrolled(false) - } - }, [isProcessing]) - - useEffect(() => { - if (isProcessing && !userScrolled) { - scrollToBottom() - } - }, [messages]) - - useEffect(() => { - const container = containerRef.current - if (!container) return - - const topObserver = new IntersectionObserver( - ([entry]) => { - setIsAtTop(entry.isIntersecting) - }, - { threshold: 1 } - ) - - const bottomObserver = new IntersectionObserver( - ([entry]) => { - setIsAtBottom(entry.isIntersecting) - if (entry.isIntersecting) { - setUserScrolled(false) - } else if (!isAutoScrolling.current) { - setUserScrolled(true) - } - }, - { threshold: 1 } - ) - - if (messagesStartRef.current) { - topObserver.observe(messagesStartRef.current) - } - - if (messagesEndRef.current) { - bottomObserver.observe(messagesEndRef.current) - } - - const resizeObserver = new ResizeObserver(() => { - setIsOverflowing(container.scrollHeight > container.clientHeight) - }) - - resizeObserver.observe(container) - - return () => { - topObserver.disconnect() - bottomObserver.disconnect() - resizeObserver.disconnect() - } - }, []) - - const scrollToTop = useCallback(() => { - if (messagesStartRef.current) { - messagesStartRef.current.scrollIntoView({ behavior: "smooth" }) - } - }, []) - - const scrollToBottom = useCallback(() => { - isAutoScrolling.current = true - - setTimeout(() => { - if (messagesEndRef.current) { - messagesEndRef.current.scrollIntoView({ behavior: "smooth" }) - } - - isAutoScrolling.current = false - }, 100) - }, []) - - return { - messagesStartRef, - messagesEndRef, - containerRef, - isAtTop, - isAtBottom, - userScrolled, - isOverflowing, - scrollToTop, - scrollToBottom, - setIsAtBottom - } -} \ No newline at end of file diff --git a/src/hooks/useSmartScroll.tsx b/src/hooks/useSmartScroll.tsx new file mode 100644 index 0000000..cad0ce4 --- /dev/null +++ b/src/hooks/useSmartScroll.tsx @@ -0,0 +1,35 @@ +import { useRef, useEffect, useState } from 'react'; + +export const useSmartScroll = (messages: any[], streaming: boolean) => { + const containerRef = useRef(null); + const [isAtBottom, setIsAtBottom] = useState(true); + + useEffect(() => { + const container = containerRef.current; + if (!container) return; + + const handleScroll = () => { + const { scrollTop, scrollHeight, clientHeight } = container; + setIsAtBottom(scrollHeight - scrollTop - clientHeight < 50); + }; + + container.addEventListener('scroll', handleScroll); + return () => container.removeEventListener('scroll', handleScroll); + }, []); + + useEffect(() => { + if (isAtBottom && containerRef.current) { + const scrollOptions: ScrollIntoViewOptions = streaming + ? { behavior: 'smooth', block: 'end' } + : { behavior: 'auto', block: 'end' }; + containerRef.current.lastElementChild?.scrollIntoView(scrollOptions); + } + }, [messages, streaming, isAtBottom]); + + const scrollToBottom = () => { + containerRef.current?.lastElementChild?.scrollIntoView({ behavior: 'smooth', block: 'end' }); + }; + + + return { containerRef, isAtBottom, scrollToBottom }; +}; diff --git a/src/libs/process-knowledge.ts b/src/libs/process-knowledge.ts index f933d85..0288e3a 100644 --- a/src/libs/process-knowledge.ts +++ b/src/libs/process-knowledge.ts @@ -12,6 +12,7 @@ import { PageAssisCSVUrlLoader } from "@/loader/csv" import { PageAssisTXTUrlLoader } from "@/loader/txt" import { PageAssistDocxLoader } from "@/loader/docx" import { cleanUrl } from "./clean-url" +import { sendEmbeddingCompleteNotification } from "./send-notification" export const processKnowledge = async (msg: any, id: string): Promise => { @@ -102,6 +103,8 @@ export const processKnowledge = async (msg: any, id: string): Promise => { } await updateKnowledgeStatus(id, "finished") + + await sendEmbeddingCompleteNotification() } catch (error) { console.error(`Error processing knowledge with id: ${id}`, error) await updateKnowledgeStatus(id, "failed") diff --git a/src/libs/send-notification.ts b/src/libs/send-notification.ts new file mode 100644 index 0000000..86a3f9c --- /dev/null +++ b/src/libs/send-notification.ts @@ -0,0 +1,29 @@ +import { Storage } from "@plasmohq/storage" +const storage = new Storage() + +export const sendNotification = async (title: string, message: string) => { + try { + const sendNotificationAfterIndexing = await storage.get( + "sendNotificationAfterIndexing" + ) + if (sendNotificationAfterIndexing) { + console.log("Sending notification") + browser.notifications.create({ + type: "basic", + iconUrl: browser.runtime.getURL("/icon/128.png"), + title, + message + }) + console.log("Notification sent") + } + } catch (error) { + console.error(error) + } +} + +export const sendEmbeddingCompleteNotification = async () => { + await sendNotification( + "Page Assist - Embedding Completed", + "The knowledge base embedding process is complete. You can now use the knowledge base for chatting." + ) +} diff --git a/src/public/_locales/en/messages.json b/src/public/_locales/en/messages.json index 6e3f66b..a574d20 100644 --- a/src/public/_locales/en/messages.json +++ b/src/public/_locales/en/messages.json @@ -7,5 +7,8 @@ }, "openSidePanelToChat": { "message": "Open Copilot to Chat" + }, + "openOptionToChat": { + "message": "Open Web UI to Chat" } } \ No newline at end of file diff --git a/src/queue/index.ts b/src/queue/index.ts index f35a382..6ea810f 100644 --- a/src/queue/index.ts +++ b/src/queue/index.ts @@ -3,4 +3,22 @@ import PubSub from "pubsub-js" export const KNOWLEDGE_QUEUE = Symbol("queue") -PubSub.subscribe(KNOWLEDGE_QUEUE, processKnowledge) +let isProcessing = false + +PubSub.subscribe(KNOWLEDGE_QUEUE, async (msg, id) => { + try { + isProcessing = true + await processKnowledge(msg, id) + isProcessing = false + } catch (error) { + console.error(error) + isProcessing = false + } +}) + +window.addEventListener("beforeunload", (event) => { + if (isProcessing) { + event.preventDefault() + event.returnValue = "" + } +}) diff --git a/src/services/app.ts b/src/services/app.ts index ca16437..c442bd9 100644 --- a/src/services/app.ts +++ b/src/services/app.ts @@ -80,3 +80,21 @@ export const getCustomOllamaHeaders = async (): Promise< return headerMap } + +export const getOpenOnIconClick = async (): Promise => { + const openOnIconClick = await storage.get("openOnIconClick"); + return openOnIconClick || "webUI"; +}; + +export const setOpenOnIconClick = async (option: "webUI" | "sidePanel"): Promise => { + await storage.set("openOnIconClick", option); +}; + +export const getOpenOnRightClick = async (): Promise => { + const openOnRightClick = await storage.get("openOnRightClick"); + return openOnRightClick || "sidePanel"; +}; + +export const setOpenOnRightClick = async (option: "webUI" | "sidePanel"): Promise => { + await storage.set("openOnRightClick", option); +}; diff --git a/src/services/model-settings.ts b/src/services/model-settings.ts index 278576d..501bf59 100644 --- a/src/services/model-settings.ts +++ b/src/services/model-settings.ts @@ -2,100 +2,127 @@ import { Storage } from "@plasmohq/storage" const storage = new Storage() type ModelSettings = { - f16KV?: boolean - frequencyPenalty?: number - keepAlive?: string - logitsAll?: boolean - mirostat?: number - mirostatEta?: number - mirostatTau?: number - numBatch?: number - numCtx?: number - numGpu?: number - numGqa?: number - numKeep?: number - numPredict?: number - numThread?: number - penalizeNewline?: boolean - presencePenalty?: number - repeatLastN?: number - repeatPenalty?: number - ropeFrequencyBase?: number - ropeFrequencyScale?: number - temperature?: number - tfsZ?: number - topK?: number - topP?: number - typicalP?: number - useMLock?: boolean - useMMap?: boolean - vocabOnly?: boolean + f16KV?: boolean + frequencyPenalty?: number + keepAlive?: string + logitsAll?: boolean + mirostat?: number + mirostatEta?: number + mirostatTau?: number + numBatch?: number + numCtx?: number + numGpu?: number + numGqa?: number + numKeep?: number + numPredict?: number + numThread?: number + penalizeNewline?: boolean + presencePenalty?: number + repeatLastN?: number + repeatPenalty?: number + ropeFrequencyBase?: number + ropeFrequencyScale?: number + temperature?: number + tfsZ?: number + topK?: number + topP?: number + typicalP?: number + useMLock?: boolean + useMMap?: boolean + vocabOnly?: boolean } const keys = [ - "f16KV", - "frequencyPenalty", - "keepAlive", - "logitsAll", - "mirostat", - "mirostatEta", - "mirostatTau", - "numBatch", - "numCtx", - "numGpu", - "numGqa", - "numKeep", - "numPredict", - "numThread", - "penalizeNewline", - "presencePenalty", - "repeatLastN", - "repeatPenalty", - "ropeFrequencyBase", - "ropeFrequencyScale", - "temperature", - "tfsZ", - "topK", - "topP", - "typicalP", - "useMLock", - "useMMap", - "vocabOnly" + "f16KV", + "frequencyPenalty", + "keepAlive", + "logitsAll", + "mirostat", + "mirostatEta", + "mirostatTau", + "numBatch", + "numCtx", + "numGpu", + "numGqa", + "numKeep", + "numPredict", + "numThread", + "penalizeNewline", + "presencePenalty", + "repeatLastN", + "repeatPenalty", + "ropeFrequencyBase", + "ropeFrequencyScale", + "temperature", + "tfsZ", + "topK", + "topP", + "typicalP", + "useMLock", + "useMMap", + "vocabOnly" ] const getAllModelSettings = async () => { - try { - const settings: ModelSettings = {} - for (const key of keys) { - const value = await storage.get(key) - settings[key] = value - if (!value && key === "keepAlive") { - settings[key] = "5m" - } - - } - return settings - } catch (error) { - console.error(error) - return {} + try { + const settings: ModelSettings = {} + for (const key of keys) { + const value = await storage.get(key) + settings[key] = value + if (!value && key === "keepAlive") { + settings[key] = "5m" + } } + return settings + } catch (error) { + console.error(error) + return {} + } } -const setModelSetting = async (key: string, - value: string | number | boolean) => { - await storage.set(key, value) +const setModelSetting = async ( + key: string, + value: string | number | boolean +) => { + await storage.set(key, value) } export const getAllDefaultModelSettings = async (): Promise => { - const settings: ModelSettings = {} - for (const key of keys) { - const value = await storage.get(key) - settings[key] = value - if (!value && key === "keepAlive") { - settings[key] = "5m" - } + const settings: ModelSettings = {} + for (const key of keys) { + const value = await storage.get(key) + settings[key] = value + if (!value && key === "keepAlive") { + settings[key] = "5m" } - return settings + } + return settings } -export { getAllModelSettings, setModelSetting } \ No newline at end of file +export const lastUsedChatModelEnabled = async (): Promise => { + const isLastUsedChatModelEnabled = await storage.get( + "restoreLastChatModel" + ) + return isLastUsedChatModelEnabled ?? false +} + +export const setLastUsedChatModelEnabled = async ( + enabled: boolean +): Promise => { + await storage.set("restoreLastChatModel", enabled) +} + +export const getLastUsedChatModel = async ( + historyId: string +): Promise => { + return await storage.get(`lastUsedChatModel-${historyId}`) +} + +export const setLastUsedChatModel = async ( + historyId: string, + model: string +): Promise => { + await storage.set(`lastUsedChatModel-${historyId}`, model) +} + +export { getAllModelSettings, setModelSetting } diff --git a/wxt.config.ts b/wxt.config.ts index 910475e..5c31a73 100644 --- a/wxt.config.ts +++ b/wxt.config.ts @@ -11,7 +11,8 @@ const chromeMV3Permissions = [ "action", "unlimitedStorage", "contextMenus", - "tts" + "tts", + "notifications" ] const firefoxMV2Permissions = [ @@ -22,6 +23,7 @@ const firefoxMV2Permissions = [ "contextMenus", "webRequest", "webRequestBlocking", + "notifications", "http://*/*", "https://*/*", "file://*/*" @@ -48,7 +50,7 @@ export default defineConfig({ outDir: "build", manifest: { - version: "1.1.14", + version: "1.1.15", name: process.env.TARGET === "firefox" ? "Page Assist - A Web UI for Local AI Models"