Merge pull request #137 from n4ze3m/next

v1.1.15
This commit is contained in:
Muhammed Nazeem 2024-07-16 10:47:47 +05:30 committed by GitHub
commit abc9a0c0be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 1371 additions and 1137 deletions

View File

@ -51,7 +51,7 @@
"chatWithCurrentPage": "Chat with current page", "chatWithCurrentPage": "Chat with current page",
"beta": "Beta", "beta": "Beta",
"tts": "Read aloud", "tts": "Read aloud",
"currentChatModelSettings":"Current Chat Model Settings", "currentChatModelSettings": "Current Chat Model Settings",
"modelSettings": { "modelSettings": {
"label": "Model Settings", "label": "Model Settings",
"description": "Set the model options globally for all chats", "description": "Set the model options globally for all chats",

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "Pending", "pending": "Pending",
"finished": "Finished", "finished": "Finished",
"processing": "Processing" "processing": "Processing",
"failed": "Failed"
}, },
"addKnowledge": "Add Knowledge", "addKnowledge": "Add Knowledge",
"form": { "form": {

View File

@ -1,307 +1,313 @@
{ {
"generalSettings": { "generalSettings": {
"title": "General Settings", "title": "General Settings",
"settings": { "settings": {
"heading": "Web UI Settings", "heading": "Web UI Settings",
"speechRecognitionLang": { "speechRecognitionLang": {
"label": "Speech Recognition Language", "label": "Speech Recognition Language",
"placeholder": "Select a language" "placeholder": "Select a language"
}, },
"language": { "language": {
"label": "Language", "label": "Language",
"placeholder": "Select a language" "placeholder": "Select a language"
}, },
"darkMode": { "darkMode": {
"label": "Change Theme", "label": "Change Theme",
"options": { "options": {
"light": "Light", "light": "Light",
"dark": "Dark" "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)"
}
} }
},
"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": { "webSearch": {
"title": "Manage Models", "heading": "Manage Web Search",
"addBtn": "Add New Model", "searchMode": {
"columns": { "label": "Perform Simple Internet Search"
"name": "Name", },
"digest": "Digest", "provider": {
"modifiedAt": "Modified At", "label": "Search Engine",
"size": "Size", "placeholder": "Select a search engine"
"actions": "Actions" },
}, "totalSearchResults": {
"expandedColumns": { "label": "Total Search Results",
"parentModel": "Parent Model", "placeholder": "Enter Total Search Results"
"format": "Format", },
"family": "Family", "visitSpecificWebsite": {
"parameterSize": "Parameter Size", "label": "Visit the website mentioned in the message"
"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": { "system": {
"title": "Manage Prompts", "heading": "System Settings",
"addBtn": "Add New Prompt", "deleteChatHistory": {
"option1": "Normal", "label": "Delete Chat History",
"option2": "RAG", "button": "Delete",
"questionPrompt": "Question Prompt", "confirm": "Are you sure you want to delete your chat history? This action cannot be undone."
"columns": { },
"title": "Title", "export": {
"prompt": "Prompt", "label": "Export Chat History, Knowledge Base, and Prompts",
"type": "Prompt Type", "button": "Export Data",
"actions": "Actions" "success": "Export Success"
}, },
"systemPrompt": "System Prompt", "import": {
"quickPrompt": "Quick Prompt", "label": "Import Chat History, Knowledge Base, and Prompts",
"tooltip": { "button": "Import Data",
"delete": "Delete Prompt", "success": "Import Success",
"edit": "Edit Prompt" "error": "Import Error"
}, }
"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": { "tts": {
"title": "Manage Share", "heading": "Text-to-Speech Settings",
"heading": "Configure Page Share URL", "ttsEnabled": {
"form": { "label": "Enable Text-to-Speech"
"url": { },
"label": "Page Share URL", "ttsProvider": {
"placeholder": "Enter Page Share URL", "label": "Text-to-Speech Provider",
"required": "Please input your Page Share URL!", "placeholder": "Select a provider"
"help": "For privacy reasons, you can self-host the page share and provide the URL here. <anchor>Learn More</anchor>." },
} "ttsVoice": {
}, "label": "Text-to-Speech Voice",
"webshare": { "placeholder": "Select a voice"
"heading": "Web Share", },
"columns": { "ssmlEnabled": {
"title": "Title", "label": "Enable SSML (Speech Synthesis Markup Language)"
"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, <anchor>click here</anchor>."
}
}
},
"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"
} }
} },
"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. <anchor>Learn More</anchor>."
}
},
"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, <anchor>click here</anchor>."
}
}
},
"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"
}
}

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "Pendiente", "pending": "Pendiente",
"finished": "Finalizado", "finished": "Finalizado",
"processing": "Procesando" "processing": "Procesando",
"failed": "Fallido"
}, },
"addKnowledge": "Agregar Conocimiento", "addKnowledge": "Agregar Conocimiento",
"form": { "form": {

View File

@ -1,307 +1,313 @@
{ {
"generalSettings": { "generalSettings": {
"title": "Configuraciones Generales", "title": "Configuraciones Generales",
"settings": { "settings": {
"heading": "Configuraciones de la Interfaz Web", "heading": "Configuraciones de la Interfaz Web",
"speechRecognitionLang": { "speechRecognitionLang": {
"label": "Idioma de Reconocimiento de Voz", "label": "Idioma de Reconocimiento de Voz",
"placeholder": "Selecione un idioma" "placeholder": "Selecione un idioma"
}, },
"language": { "language": {
"label": "Idioma", "label": "Idioma",
"placeholder": "Selecione un idioma" "placeholder": "Selecione un idioma"
}, },
"darkMode": { "darkMode": {
"label": "Cambiar Tema", "label": "Cambiar Tema",
"options": { "options": {
"light": "Claro", "light": "Claro",
"dark": "Oscuro" "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)"
}
} }
},
"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": { "webSearch": {
"title": "Administar de Modelos", "heading": "Manejo de la busqueda Web",
"addBtn": "Agregar Nuevo Modelo", "searchMode": {
"columns": { "label": "Realizar busquedas Simples en Internet"
"name": "Nombre", },
"digest": "Resumen", "provider": {
"modifiedAt": "Modificado", "label": "Motor de Busqueda",
"size": "Tamaño", "placeholder": "Selecione un motor de busqueda"
"actions": "Acciones" },
}, "totalSearchResults": {
"expandedColumns": { "label": "Resultados totales de la busqueda",
"parentModel": "Modelo Padre", "placeholder": "Ingresar el total de Resultados de la busqueda"
"format": "Formato", },
"family": "Familia", "visitSpecificWebsite": {
"parameterSize": "Tamaño de Parametros", "label": "Visita el sitio web mencionado en el mensaje"
"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": { "system": {
"title": "Administrar de Prompts", "heading": "Configuraciones del Sistema",
"addBtn": "Agregar Nuevo Prompt", "deleteChatHistory": {
"option1": "Normal", "label": "Borrar Histórico del Chat",
"option2": "RAG", "button": "Borrar",
"questionPrompt": "Prompt de Pregunta", "confirm": "¿Esta seguro que desea borrar su histórico del chat? Esta acción no podra ser desecha."
"columns": { },
"title": "Título", "export": {
"prompt": "Prompt", "label": "Exportar Histórico del Chat, Base de Conocimiento y Prompts",
"type": "Tipo de Prompt", "button": "Exportar Datos",
"actions": "Acciones" "success": "Exportación exitosa"
}, },
"systemPrompt": "Prompt del Sistema", "import": {
"quickPrompt": "Prompt Rápido", "label": "Importar Histórico del Chat, Base de Conocimiento y Prompts",
"tooltip": { "button": "Importar Datos",
"delete": "Borrar Prompt", "success": "Importación existosa",
"edit": "Editar Prompt" "error": "Error de importación"
}, }
"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": { "tts": {
"title": "Administrar los recursos compartidos", "heading": "Configuraciones de Text-to-speech",
"heading": "Configurar URL de Página Compartida", "ttsEnabled": {
"form": { "label": "Habilitar Texto-a-Voz"
"url": { },
"label": "URL de Página compartida", "ttsProvider": {
"placeholder": "Ingresar URL de Página compartida", "label": "Proveedor de Text-to-speech",
"required": "Por favor, ingrese URL de Página compartida", "placeholder": "Selecione un proveedor"
"help": "Por motivos de privacidad, podes hacer self-host de la página compartida y proveer una URL aqui. <anchor>Aprende más</anchor>." },
} "ttsVoice": {
}, "label": "Voz de Text-to-speech",
"webshare": { "placeholder": "Selecione una voz"
"heading": "Compartir una Web", },
"columns": { "ssmlEnabled": {
"title": "Título", "label": "Habilitar SSML (Speech Synthesis Markup Language)"
"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, <anchor>click aqui</anchor>."
}
}
},
"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"
} }
} },
"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. <anchor>Aprende más</anchor>."
}
},
"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, <anchor>click aqui</anchor>."
}
}
},
"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"
}
}

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "En attente", "pending": "En attente",
"finished": "Terminé", "finished": "Terminé",
"processing": "Traitement" "processing": "Traitement",
"failed": "Échoué"
}, },
"addKnowledge": "Ajouter des connaissances", "addKnowledge": "Ajouter des connaissances",
"form": { "form": {

View File

@ -1,307 +1,313 @@
{ {
"generalSettings": { "generalSettings": {
"title": "Réglages généraux", "title": "Réglages généraux",
"settings": { "settings": {
"heading": "Paramètres d'interface utilisateur Web", "heading": "Paramètres d'interface utilisateur Web",
"speechRecognitionLang": { "speechRecognitionLang": {
"label": "Langue de reconnaissance vocale", "label": "Langue de reconnaissance vocale",
"placeholder": "Sélectionnez une langue" "placeholder": "Sélectionnez une langue"
}, },
"language": { "language": {
"label": "Langue", "label": "Langue",
"placeholder": "Sélectionnez une langue" "placeholder": "Sélectionnez une langue"
}, },
"darkMode": { "darkMode": {
"label": "Change le thème", "label": "Change le thème",
"options": { "options": {
"light": "Clair", "light": "Clair",
"dark": "Sombre" "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)"
}
} }
},
"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": { "webSearch": {
"title": "Gérer les modèles", "heading": "Gérer la recherche Web",
"addBtn": "Ajouter un nouveau modèle", "searchMode": {
"columns": { "label": "Effectuer une simple recherche sur Internet"
"name": "Nom", },
"digest": "Digérer", "provider": {
"modifiedAt": "Modifié à", "label": "Moteur de recherche",
"size": "Taille", "placeholder": "Sélectionnez un moteur de recherche"
"actions": "Actions" },
}, "totalSearchResults": {
"expandedColumns": { "label": "Résultats de la recherche totaux",
"parentModel": "Modèle parent", "placeholder": "Entrez les résultats de la recherche totaux"
"format": "Format", },
"family": "Famille", "visitSpecificWebsite": {
"parameterSize": "Taille du paramètre", "label": "Visitez le site web mentionné dans le message"
"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": { "system": {
"title": "Gérer les prompts", "heading": "Les paramètres du système",
"addBtn": "Ajouter un nouveau prompt", "deleteChatHistory": {
"option1": "Normale", "label": "Supprimer l'historique du chat",
"option2": "RAG", "button": "Supprimer",
"questionPrompt": "Prompt de question", "confirm": "Êtes-vous sûr de vouloir supprimer l'historique de votre chat? Cette action ne peut pas être annulée."
"columns": { },
"title": "Titre", "export": {
"prompt": "Prompt", "label": "Exporter l'historique du chat, la base de connaissances et les invites",
"type": "Type de prompt", "button": "Exporter des données",
"actions": "Actions" "success": "Succès de l'exportation"
}, },
"systemPrompt": "Prompt système", "import": {
"quickPrompt": "Prompt rapide", "label": "Importer l'historique du chat, la base de connaissances et les invites",
"tooltip": { "button": "Importer des données",
"delete": "Supprimer le prompt", "success": "Succès d'importation",
"edit": "Modifier le prompt" "error": "Erreur d'importation"
}, }
"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": { "tts": {
"title": "Gérer le partage", "heading": "Paramètres de synthèse vocale",
"heading": "Configurer l'URL de partage de la page", "ttsEnabled": {
"form": { "label": "Activer la synthèse vocale"
"url": { },
"label": "URL de partage de page", "ttsProvider": {
"placeholder": "Entrez l'URL de partage de la page", "label": "Fournisseur de synthèse vocale",
"required": "Veuillez saisir URL de partage de votre page!", "placeholder": "Sélectionnez un fournisseur"
"help": "Pour des raisons de confidentialité, vous pouvez auto-héberger le partage de la page et fournir l'URL ici.<anchor>En savoir plus</anchor>." },
} "ttsVoice": {
}, "label": "Voix de synthèse vocale",
"webshare": { "placeholder": "Sélectionnez une voix"
"heading": "Partage Web", },
"columns": { "ssmlEnabled": {
"title": "Titre", "label": "Activer SSML (langage de balisage de synthèse vocale)"
"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, <anchor>cliquez ici</anchor>."
}
}
},
"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"
} }
} },
"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.<anchor>En savoir plus</anchor>."
}
},
"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, <anchor>cliquez ici</anchor>."
}
}
},
"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"
}
}

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "In attesa", "pending": "In attesa",
"finished": "Completato", "finished": "Completato",
"processing": "In corso" "processing": "In corso",
"failed": "Fallito"
}, },
"addKnowledge": "Aggiungi Knowledge Base", "addKnowledge": "Aggiungi Knowledge Base",
"form": { "form": {

View File

@ -23,6 +23,12 @@
}, },
"hideCurrentChatModelSettings": { "hideCurrentChatModelSettings": {
"label": "Nascondi le impostazioni correnti del modello Chat" "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": { "webSearch": {

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "保留中", "pending": "保留中",
"finished": "完了", "finished": "完了",
"processing": "処理中" "processing": "処理中",
"failed": "失敗"
}, },
"addKnowledge": "知識を追加", "addKnowledge": "知識を追加",
"form": { "form": {

View File

@ -26,6 +26,12 @@
}, },
"hideCurrentChatModelSettings": { "hideCurrentChatModelSettings": {
"label": "現在のチャットモデル設定を非表示" "label": "現在のチャットモデル設定を非表示"
},
"restoreLastChatModel": {
"label": "以前のチャットで最後に使用したモデルを復元する"
},
"sendNotificationAfterIndexing": {
"label": "ナレッジベースの処理完了後に通知を送信"
} }
}, },
"webSearch": { "webSearch": {
@ -306,5 +312,5 @@
}, },
"chromeAiSettings": { "chromeAiSettings": {
"title": "Chrome AI設定" "title": "Chrome AI設定"
} }
} }

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "തീരുമാനിക്കാനുണ്ട്", "pending": "തീരുമാനിക്കാനുണ്ട്",
"finished": "പൂർത്തീകരിച്ചു", "finished": "പൂർത്തീകരിച്ചു",
"processing": "പ്രോസസ്സിംഗ്" "processing": "പ്രോസസ്സിംഗ്",
"failed": "പരാജയപ്പെട്ടു"
}, },
"addKnowledge": "വിജ്ഞാനം ചേര്‍ക്കുക", "addKnowledge": "വിജ്ഞാനം ചേര്‍ക്കുക",
"form": { "form": {

View File

@ -26,6 +26,12 @@
}, },
"hideCurrentChatModelSettings": { "hideCurrentChatModelSettings": {
"label": "നിലവിലുള്ള ചാറ്റ് മോഡൽ ക്രമീകരണങ്ങൾ മറയ്ക്കുക" "label": "നിലവിലുള്ള ചാറ്റ് മോഡൽ ക്രമീകരണങ്ങൾ മറയ്ക്കുക"
},
"restoreLastChatModel": {
"label": "മുൻപത്തെ ചാറ്റുകൾക്കായി അവസാനം ഉപയോഗിച്ച മോഡൽ പുനഃസ്ഥാപിക്കുക"
},
"sendNotificationAfterIndexing": {
"label": "അറിവ് ശേഖരം പ്രോസസ്സ് ചെയ്ത് കഴിഞ്ഞതിന് ശേഷം അറിയിപ്പ് അയയ്ക്കുക"
} }
}, },
"webSearch": { "webSearch": {

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "Pendente", "pending": "Pendente",
"finished": "Concluído", "finished": "Concluído",
"processing": "Processando" "processing": "Processando",
"failed": "Falhou"
}, },
"addKnowledge": "Adicionar Conhecimento", "addKnowledge": "Adicionar Conhecimento",
"form": { "form": {

View File

@ -23,6 +23,12 @@
}, },
"hideCurrentChatModelSettings": { "hideCurrentChatModelSettings": {
"label": "Ocultar as Configurações Atuais do Modelo de Chat" "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": { "webSearch": {
@ -304,4 +310,4 @@
"chromeAiSettings": { "chromeAiSettings": {
"title": "Configurações do Chrome AI" "title": "Configurações do Chrome AI"
} }
} }

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "Ожидание", "pending": "Ожидание",
"finished": "Завершено", "finished": "Завершено",
"processing": "Обработка" "processing": "Обработка",
"failed": "Не удалось"
}, },
"addKnowledge": "Добавить знание", "addKnowledge": "Добавить знание",
"form": { "form": {

View File

@ -23,6 +23,12 @@
}, },
"hideCurrentChatModelSettings": { "hideCurrentChatModelSettings": {
"label": "Скрыть текущие настройки модели чата" "label": "Скрыть текущие настройки модели чата"
},
"restoreLastChatModel": {
"label": "Восстановить последнюю использованную модель для предыдущих чатов"
},
"sendNotificationAfterIndexing": {
"label": "Отправить уведомление после завершения обработки базы знаний"
} }
}, },
"webSearch": { "webSearch": {
@ -304,5 +310,5 @@
}, },
"chromeAiSettings": { "chromeAiSettings": {
"title": "Настройки ИИ Chrome" "title": "Настройки ИИ Chrome"
} }
} }

View File

@ -20,7 +20,8 @@
"status": { "status": {
"pending": "待定", "pending": "待定",
"finished": "已完成", "finished": "已完成",
"processing": "处理中" "processing": "处理中",
"failed": "失败"
}, },
"addKnowledge": "添加知识", "addKnowledge": "添加知识",
"form": { "form": {

View File

@ -26,6 +26,12 @@
}, },
"hideCurrentChatModelSettings": { "hideCurrentChatModelSettings": {
"label": "隐藏当前聊天模型设置" "label": "隐藏当前聊天模型设置"
},
"restoreLastChatModel": {
"label": "恢复上次用于之前聊天的模型"
},
"sendNotificationAfterIndexing": {
"label": "完成知识库处理后发送通知"
} }
}, },
"webSearch": { "webSearch": {

View File

@ -65,3 +65,63 @@
animation: gradient-border 3s infinite; animation: gradient-border 3s infinite;
border-radius: 10px; 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;
}

View File

@ -37,8 +37,9 @@ export const KnowledgeSettings = () => {
const statusColor = { const statusColor = {
finished: "green", finished: "green",
processing: "blue", processing: "yellow",
pending: "gray" pending: "gray",
failed: "red"
} }
return ( return (

View File

@ -78,6 +78,7 @@ export const Playground = () => {
dropState === "dragging" ? "bg-gray-100 dark:bg-gray-800 z-10" : "" dropState === "dragging" ? "bg-gray-100 dark:bg-gray-800 z-10" : ""
} bg-white dark:bg-[#171717]`}> } bg-white dark:bg-[#171717]`}>
<PlaygroundChat /> <PlaygroundChat />
<div className="flex flex-col items-center"> <div className="flex flex-col items-center">
<div className="flex-grow"> <div className="flex-grow">
<div className="w-full flex justify-center"> <div className="w-full flex justify-center">

View File

@ -3,6 +3,8 @@ import { useMessageOption } from "~/hooks/useMessageOption"
import { PlaygroundEmpty } from "./PlaygroundEmpty" import { PlaygroundEmpty } from "./PlaygroundEmpty"
import { PlaygroundMessage } from "~/components/Common/Playground/Message" import { PlaygroundMessage } from "~/components/Common/Playground/Message"
import { MessageSourcePopup } from "@/components/Common/Playground/MessageSourcePopup" import { MessageSourcePopup } from "@/components/Common/Playground/MessageSourcePopup"
import { useSmartScroll } from "~/hooks/useSmartScroll"
import { ChevronDown } from "lucide-react"
export const PlaygroundChat = () => { export const PlaygroundChat = () => {
const { const {
@ -13,24 +15,24 @@ export const PlaygroundChat = () => {
editMessage, editMessage,
ttsEnabled ttsEnabled
} = useMessageOption() } = useMessageOption()
const divRef = React.useRef<HTMLDivElement>(null)
const [isSourceOpen, setIsSourceOpen] = React.useState(false) const [isSourceOpen, setIsSourceOpen] = React.useState(false)
const [source, setSource] = React.useState<any>(null) const [source, setSource] = React.useState<any>(null)
React.useEffect(() => {
if (divRef.current) { const { containerRef, isAtBottom, scrollToBottom } = useSmartScroll(
divRef.current.scrollIntoView({ behavior: "smooth" }) messages,
} streaming
}) )
return ( return (
<> <>
{" "} <div
<div className="grow flex flex-col md:translate-x-0 transition-transform duration-300 ease-in-out"> ref={containerRef}
className="custom-scrollbar grow flex flex-col md:translate-x-0 transition-transform duration-300 ease-in-out overflow-y-auto h-[calc(100vh-200px)]">
{messages.length === 0 && ( {messages.length === 0 && (
<div className="mt-32"> <div className="mt-32">
<PlaygroundEmpty /> <PlaygroundEmpty />
</div> </div>
)} )}
{/* {messages.length > 0 && <div className="w-full h-16 flex-shrink-0"></div>} */}
{messages.map((message, index) => ( {messages.map((message, index) => (
<PlaygroundMessage <PlaygroundMessage
key={index} key={index}
@ -55,10 +57,18 @@ export const PlaygroundChat = () => {
/> />
))} ))}
{messages.length > 0 && ( {messages.length > 0 && (
<div className="w-full h-32 md:h-48 flex-shrink-0"></div> <div className="w-full h-16 flex-shrink-0"></div>
)} )}
<div ref={divRef} />
</div> </div>
{!isAtBottom && (
<div className="fixed md:bottom-44 bottom-36 z-[9999999] left-0 right-0 flex justify-center">
<button
onClick={scrollToBottom}
className="bg-gray-100 dark:bg-gray-800 p-1 rounded-full shadow-md hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200">
<ChevronDown className="size-4 text-gray-600 dark:text-gray-300" />
</button>
</div>
)}
<MessageSourcePopup <MessageSourcePopup
open={isSourceOpen} open={isSourceOpen}
setOpen={setIsSourceOpen} setOpen={setIsSourceOpen}

View File

@ -24,9 +24,17 @@ export const GeneralSettings = () => {
false false
) )
const [restoreLastChatModel, setRestoreLastChatModel] = useStorage(
"restoreLastChatModel",
false
)
const [hideCurrentChatModelSettings, setHideCurrentChatModelSettings] = const [hideCurrentChatModelSettings, setHideCurrentChatModelSettings] =
useStorage("hideCurrentChatModelSettings", false) useStorage("hideCurrentChatModelSettings", false)
const [sendNotificationAfterIndexing, setSendNotificationAfterIndexing] =
useStorage("sendNotificationAfterIndexing", false)
const queryClient = useQueryClient() const queryClient = useQueryClient()
const { mode, toggleDarkMode } = useDarkMode() const { mode, toggleDarkMode } = useDarkMode()
@ -107,6 +115,32 @@ export const GeneralSettings = () => {
onChange={(checked) => setHideCurrentChatModelSettings(checked)} onChange={(checked) => setHideCurrentChatModelSettings(checked)}
/> />
</div> </div>
<div className="flex flex-row justify-between">
<div className="inline-flex items-center gap-2">
<span className="text-gray-700 dark:text-neutral-50">
{t("generalSettings.settings.restoreLastChatModel.label")}
</span>
</div>
<Switch
checked={restoreLastChatModel}
onChange={(checked) => setRestoreLastChatModel(checked)}
/>
</div>
<div className="flex flex-row justify-between">
<div className="inline-flex items-center gap-2">
<span className="text-gray-700 dark:text-neutral-50">
{t("generalSettings.settings.sendNotificationAfterIndexing.label")}
</span>
</div>
<Switch
checked={sendNotificationAfterIndexing}
onChange={setSendNotificationAfterIndexing}
/>
</div>
<div className="flex flex-row justify-between"> <div className="flex flex-row justify-between">
<span className="text-gray-700 dark:text-neutral-50 "> <span className="text-gray-700 dark:text-neutral-50 ">
{t("generalSettings.settings.darkMode.label")} {t("generalSettings.settings.darkMode.label")}

View File

@ -11,14 +11,24 @@ import { useMessageOption } from "~/hooks/useMessageOption"
import { PencilIcon, Trash2 } from "lucide-react" import { PencilIcon, Trash2 } from "lucide-react"
import { useNavigate } from "react-router-dom" import { useNavigate } from "react-router-dom"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
import {
getLastUsedChatModel,
lastUsedChatModelEnabled
} from "@/services/model-settings"
type Props = { type Props = {
onClose: () => void onClose: () => void
} }
export const Sidebar = ({ onClose }: Props) => { export const Sidebar = ({ onClose }: Props) => {
const { setMessages, setHistory, setHistoryId, historyId, clearChat } = const {
useMessageOption() setMessages,
setHistory,
setHistoryId,
historyId,
clearChat,
setSelectedModel
} = useMessageOption()
const { t } = useTranslation(["option", "common"]) const { t } = useTranslation(["option", "common"])
const client = useQueryClient() const client = useQueryClient()
const navigate = useNavigate() const navigate = useNavigate()
@ -88,6 +98,13 @@ export const Sidebar = ({ onClose }: Props) => {
setHistoryId(chat.id) setHistoryId(chat.id)
setHistory(formatToChatHistory(history)) setHistory(formatToChatHistory(history))
setMessages(formatToMessage(history)) setMessages(formatToMessage(history))
const isLastUsedChatModel = await lastUsedChatModelEnabled()
if (isLastUsedChatModel) {
const currentChatModel = await getLastUsedChatModel(chat.id)
if (currentChatModel) {
setSelectedModel(currentChatModel)
}
}
navigate("/") navigate("/")
onClose() onClose()
}}> }}>

View File

@ -1,6 +1,7 @@
import { getOllamaURL, isOllamaRunning } from "../services/ollama" import { getOllamaURL, isOllamaRunning } from "../services/ollama"
import { browser } from "wxt/browser" import { browser } from "wxt/browser"
import { setBadgeBackgroundColor, setBadgeText, setTitle } from "@/utils/action" import { setBadgeBackgroundColor, setBadgeText, setTitle } from "@/utils/action"
const progressHuman = (completed: number, total: number) => { const progressHuman = (completed: number, total: number) => {
return ((completed / total) * 100).toFixed(0) + "%" return ((completed / total) * 100).toFixed(0) + "%"
} }
@ -75,11 +76,12 @@ const streamDownload = async (url: string, model: string) => {
clearBadge() clearBadge()
}, 5000) }, 5000)
} }
export default defineBackground({ export default defineBackground({
main() { main() {
browser.runtime.onMessage.addListener(async (message) => { browser.runtime.onMessage.addListener(async (message) => {
if (message.type === "sidepanel") { if (message.type === "sidepanel") {
browser.sidebarAction.open() await browser.sidebarAction.open()
} else if (message.type === "pull_model") { } else if (message.type === "pull_model") {
const ollamaURL = await getOllamaURL() const ollamaURL = await getOllamaURL()
@ -100,7 +102,7 @@ export default defineBackground({
if (import.meta.env.BROWSER === "chrome") { if (import.meta.env.BROWSER === "chrome") {
chrome.action.onClicked.addListener((tab) => { chrome.action.onClicked.addListener((tab) => {
browser.tabs.create({ url: browser.runtime.getURL("/options.html") }) chrome.tabs.create({ url: chrome.runtime.getURL("/options.html") })
}) })
} else { } else {
browser.browserAction.onClicked.addListener((tab) => { 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({ browser.contextMenus.create({
id: "open-side-panel-pa", id: contextMenuId["sidePanel"],
title: browser.i18n.getMessage("openSidePanelToChat"), title: contextMenuTitle["sidePanel"],
contexts: ["all"] contexts: ["all"]
}) })
if (import.meta.env.BROWSER === "chrome") { if (import.meta.env.BROWSER === "chrome") {
browser.contextMenus.onClicked.addListener((info, tab) => { browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "open-side-panel-pa") { if (info.menuItemId === "open-side-panel-pa") {
chrome.tabs.query( chrome.sidePanel.open({
{ active: true, currentWindow: true }, tabId: tab.id!
async (tabs) => { })
const tab = tabs[0] } else if (info.menuItemId === "open-web-ui-pa") {
chrome.sidePanel.open({ browser.tabs.create({
tabId: tab.id! url: browser.runtime.getURL("/options.html")
}) })
}
)
} }
}) })
@ -152,6 +162,10 @@ export default defineBackground({
browser.contextMenus.onClicked.addListener((info, tab) => { browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "open-side-panel-pa") { if (info.menuItemId === "open-side-panel-pa") {
browser.sidebarAction.toggle() browser.sidebarAction.toggle()
} else if (info.menuItemId === "open-web-ui-pa") {
browser.tabs.create({
url: browser.runtime.getURL("/options.html")
})
} }
}) })

View File

@ -1,4 +1,5 @@
import { saveHistory, saveMessage } from "@/db" import { saveHistory, saveMessage } from "@/db"
import { setLastUsedChatModel } from "@/services/model-settings"
import { ChatHistory } from "@/store/option" import { ChatHistory } from "@/store/option"
export const saveMessageOnError = async ({ export const saveMessageOnError = async ({
@ -23,7 +24,7 @@ export const saveMessageOnError = async ({
historyId: string | null historyId: string | null
selectedModel: string selectedModel: string
setHistoryId: (historyId: string) => void setHistoryId: (historyId: string) => void
isRegenerating: boolean, isRegenerating: boolean
message_source?: "copilot" | "web-ui" message_source?: "copilot" | "web-ui"
}) => { }) => {
if ( if (
@ -66,6 +67,7 @@ export const saveMessageOnError = async ({
[], [],
2 2
) )
await setLastUsedChatModel(historyId, selectedModel)
} else { } else {
const newHistoryId = await saveHistory(userMessage, false, message_source) const newHistoryId = await saveHistory(userMessage, false, message_source)
if (!isRegenerating) { if (!isRegenerating) {
@ -89,6 +91,7 @@ export const saveMessageOnError = async ({
2 2
) )
setHistoryId(newHistoryId.id) setHistoryId(newHistoryId.id)
await setLastUsedChatModel(newHistoryId.id, selectedModel)
} }
return true return true
@ -115,7 +118,7 @@ export const saveMessageOnSuccess = async ({
message: string message: string
image: string image: string
fullText: string fullText: string
source: any[], source: any[]
message_source?: "copilot" | "web-ui" message_source?: "copilot" | "web-ui"
}) => { }) => {
if (historyId) { if (historyId) {
@ -139,6 +142,7 @@ export const saveMessageOnSuccess = async ({
source, source,
2 2
) )
await setLastUsedChatModel(historyId, selectedModel!)
} else { } else {
const newHistoryId = await saveHistory(message, false, message_source) const newHistoryId = await saveHistory(message, false, message_source)
await saveMessage( await saveMessage(
@ -160,5 +164,6 @@ export const saveMessageOnSuccess = async ({
2 2
) )
setHistoryId(newHistoryId.id) setHistoryId(newHistoryId.id)
await setLastUsedChatModel(newHistoryId.id, selectedModel!)
} }
} }

View File

@ -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<HTMLDivElement>(null)
const messagesEndRef = useRef<HTMLDivElement>(null)
const containerRef = useRef<HTMLDivElement>(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
}
}

View File

@ -0,0 +1,35 @@
import { useRef, useEffect, useState } from 'react';
export const useSmartScroll = (messages: any[], streaming: boolean) => {
const containerRef = useRef<HTMLDivElement>(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 };
};

View File

@ -12,6 +12,7 @@ import { PageAssisCSVUrlLoader } from "@/loader/csv"
import { PageAssisTXTUrlLoader } from "@/loader/txt" import { PageAssisTXTUrlLoader } from "@/loader/txt"
import { PageAssistDocxLoader } from "@/loader/docx" import { PageAssistDocxLoader } from "@/loader/docx"
import { cleanUrl } from "./clean-url" import { cleanUrl } from "./clean-url"
import { sendEmbeddingCompleteNotification } from "./send-notification"
export const processKnowledge = async (msg: any, id: string): Promise<void> => { export const processKnowledge = async (msg: any, id: string): Promise<void> => {
@ -102,6 +103,8 @@ export const processKnowledge = async (msg: any, id: string): Promise<void> => {
} }
await updateKnowledgeStatus(id, "finished") await updateKnowledgeStatus(id, "finished")
await sendEmbeddingCompleteNotification()
} catch (error) { } catch (error) {
console.error(`Error processing knowledge with id: ${id}`, error) console.error(`Error processing knowledge with id: ${id}`, error)
await updateKnowledgeStatus(id, "failed") await updateKnowledgeStatus(id, "failed")

View File

@ -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<boolean>(
"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."
)
}

View File

@ -7,5 +7,8 @@
}, },
"openSidePanelToChat": { "openSidePanelToChat": {
"message": "Open Copilot to Chat" "message": "Open Copilot to Chat"
},
"openOptionToChat": {
"message": "Open Web UI to Chat"
} }
} }

View File

@ -3,4 +3,22 @@ import PubSub from "pubsub-js"
export const KNOWLEDGE_QUEUE = Symbol("queue") 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 = ""
}
})

View File

@ -80,3 +80,21 @@ export const getCustomOllamaHeaders = async (): Promise<
return headerMap return headerMap
} }
export const getOpenOnIconClick = async (): Promise<string> => {
const openOnIconClick = await storage.get<string>("openOnIconClick");
return openOnIconClick || "webUI";
};
export const setOpenOnIconClick = async (option: "webUI" | "sidePanel"): Promise<void> => {
await storage.set("openOnIconClick", option);
};
export const getOpenOnRightClick = async (): Promise<string> => {
const openOnRightClick = await storage.get<string>("openOnRightClick");
return openOnRightClick || "sidePanel";
};
export const setOpenOnRightClick = async (option: "webUI" | "sidePanel"): Promise<void> => {
await storage.set("openOnRightClick", option);
};

View File

@ -2,100 +2,127 @@ import { Storage } from "@plasmohq/storage"
const storage = new Storage() const storage = new Storage()
type ModelSettings = { type ModelSettings = {
f16KV?: boolean f16KV?: boolean
frequencyPenalty?: number frequencyPenalty?: number
keepAlive?: string keepAlive?: string
logitsAll?: boolean logitsAll?: boolean
mirostat?: number mirostat?: number
mirostatEta?: number mirostatEta?: number
mirostatTau?: number mirostatTau?: number
numBatch?: number numBatch?: number
numCtx?: number numCtx?: number
numGpu?: number numGpu?: number
numGqa?: number numGqa?: number
numKeep?: number numKeep?: number
numPredict?: number numPredict?: number
numThread?: number numThread?: number
penalizeNewline?: boolean penalizeNewline?: boolean
presencePenalty?: number presencePenalty?: number
repeatLastN?: number repeatLastN?: number
repeatPenalty?: number repeatPenalty?: number
ropeFrequencyBase?: number ropeFrequencyBase?: number
ropeFrequencyScale?: number ropeFrequencyScale?: number
temperature?: number temperature?: number
tfsZ?: number tfsZ?: number
topK?: number topK?: number
topP?: number topP?: number
typicalP?: number typicalP?: number
useMLock?: boolean useMLock?: boolean
useMMap?: boolean useMMap?: boolean
vocabOnly?: boolean vocabOnly?: boolean
} }
const keys = [ const keys = [
"f16KV", "f16KV",
"frequencyPenalty", "frequencyPenalty",
"keepAlive", "keepAlive",
"logitsAll", "logitsAll",
"mirostat", "mirostat",
"mirostatEta", "mirostatEta",
"mirostatTau", "mirostatTau",
"numBatch", "numBatch",
"numCtx", "numCtx",
"numGpu", "numGpu",
"numGqa", "numGqa",
"numKeep", "numKeep",
"numPredict", "numPredict",
"numThread", "numThread",
"penalizeNewline", "penalizeNewline",
"presencePenalty", "presencePenalty",
"repeatLastN", "repeatLastN",
"repeatPenalty", "repeatPenalty",
"ropeFrequencyBase", "ropeFrequencyBase",
"ropeFrequencyScale", "ropeFrequencyScale",
"temperature", "temperature",
"tfsZ", "tfsZ",
"topK", "topK",
"topP", "topP",
"typicalP", "typicalP",
"useMLock", "useMLock",
"useMMap", "useMMap",
"vocabOnly" "vocabOnly"
] ]
const getAllModelSettings = async () => { const getAllModelSettings = async () => {
try { try {
const settings: ModelSettings = {} const settings: ModelSettings = {}
for (const key of keys) { for (const key of keys) {
const value = await storage.get(key) const value = await storage.get(key)
settings[key] = value settings[key] = value
if (!value && key === "keepAlive") { if (!value && key === "keepAlive") {
settings[key] = "5m" settings[key] = "5m"
} }
}
return settings
} catch (error) {
console.error(error)
return {}
} }
return settings
} catch (error) {
console.error(error)
return {}
}
} }
const setModelSetting = async (key: string, const setModelSetting = async (
value: string | number | boolean) => { key: string,
await storage.set(key, value) value: string | number | boolean
) => {
await storage.set(key, value)
} }
export const getAllDefaultModelSettings = async (): Promise<ModelSettings> => { export const getAllDefaultModelSettings = async (): Promise<ModelSettings> => {
const settings: ModelSettings = {} const settings: ModelSettings = {}
for (const key of keys) { for (const key of keys) {
const value = await storage.get(key) const value = await storage.get(key)
settings[key] = value settings[key] = value
if (!value && key === "keepAlive") { if (!value && key === "keepAlive") {
settings[key] = "5m" settings[key] = "5m"
}
} }
return settings }
return settings
} }
export { getAllModelSettings, setModelSetting } export const lastUsedChatModelEnabled = async (): Promise<boolean> => {
const isLastUsedChatModelEnabled = await storage.get<boolean | undefined>(
"restoreLastChatModel"
)
return isLastUsedChatModelEnabled ?? false
}
export const setLastUsedChatModelEnabled = async (
enabled: boolean
): Promise<void> => {
await storage.set("restoreLastChatModel", enabled)
}
export const getLastUsedChatModel = async (
historyId: string
): Promise<string | undefined> => {
return await storage.get<string | undefined>(`lastUsedChatModel-${historyId}`)
}
export const setLastUsedChatModel = async (
historyId: string,
model: string
): Promise<void> => {
await storage.set(`lastUsedChatModel-${historyId}`, model)
}
export { getAllModelSettings, setModelSetting }

View File

@ -11,7 +11,8 @@ const chromeMV3Permissions = [
"action", "action",
"unlimitedStorage", "unlimitedStorage",
"contextMenus", "contextMenus",
"tts" "tts",
"notifications"
] ]
const firefoxMV2Permissions = [ const firefoxMV2Permissions = [
@ -22,6 +23,7 @@ const firefoxMV2Permissions = [
"contextMenus", "contextMenus",
"webRequest", "webRequest",
"webRequestBlocking", "webRequestBlocking",
"notifications",
"http://*/*", "http://*/*",
"https://*/*", "https://*/*",
"file://*/*" "file://*/*"
@ -48,7 +50,7 @@ export default defineConfig({
outDir: "build", outDir: "build",
manifest: { manifest: {
version: "1.1.14", version: "1.1.15",
name: name:
process.env.TARGET === "firefox" process.env.TARGET === "firefox"
? "Page Assist - A Web UI for Local AI Models" ? "Page Assist - A Web UI for Local AI Models"