From 18cd02d44ee9dcbe6015166f0c84a7059edf3ed2 Mon Sep 17 00:00:00 2001
From: Fuegovic <32828263+fuegovic@users.noreply.github.com>
Date: Thu, 28 Dec 2023 17:07:11 -0500
Subject: [PATCH 01/42] Update French Translation (#1444)
---
client/src/localization/languages/Fr.tsx | 29 ++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/client/src/localization/languages/Fr.tsx b/client/src/localization/languages/Fr.tsx
index a97aea8c4782..7a1863d3923f 100644
--- a/client/src/localization/languages/Fr.tsx
+++ b/client/src/localization/languages/Fr.tsx
@@ -32,6 +32,7 @@ export default {
com_ui_entries: 'Entrées',
com_ui_pay_per_call:
'Toutes les conversations IA au même endroit. Payez à la demande et non par mois',
+ com_ui_new_footer: 'Toutes les conversations IA au même endroit.',
com_ui_enter: 'Entrer',
com_ui_submit: 'Soumettre',
com_ui_upload_success: 'Fichier téléchargé avec succès',
@@ -123,6 +124,8 @@ export default {
com_endpoint_bing_system_message_placeholder:
'AVERTISSEMENT : L\'abus de cette fonctionnalité peut vous faire BANNIR de l\'utilisation de Bing ! Cliquez sur "Message système" pour obtenir les instructions complètes et le message par défaut si omis, qui est le préréglage "Sydney" qui est considéré comme sûr.',
com_endpoint_system_message: 'Message système',
+ com_endpoint_message: 'Message',
+ com_endpoint_message_not_appendable: 'Editer votre message ou regenerer.',
com_endpoint_default_blank: 'par défaut : vide',
com_endpoint_default_false: 'par défaut : faux',
com_endpoint_default_creative: 'par défaut : créatif',
@@ -183,8 +186,22 @@ export default {
com_endpoint_import: 'Importer',
com_endpoint_set_custom_name:
'Définir un nom personnalisé, au cas où vous trouveriez ce préréglage',
+ com_endpoint_preset_delete_confirm: 'Êtes-vous sûr de vouloir supprimer ce préréglage ?',
+ com_endpoint_preset_clear_all_confirm: 'Êtes-vous sûr de vouloir supprimer tous vos préréglages ?',
+ com_endpoint_preset_import: 'Préréglage importé !',
+ com_endpoint_preset_import_error: 'Il y a eu une erreur lors de l\'importation de votre préréglage. Veuillez réessayer.',
+ com_endpoint_preset_save_error: 'Il y a eu une erreur lors de la sauvegarde de votre préréglage. Veuillez réessayer.',
+ com_endpoint_preset_delete_error: 'Il y a eu une erreur lors de la suppression de votre préréglage. Veuillez réessayer.',
+ com_endpoint_preset_default_removed: 'n\'est plus le préréglage par défaut.',
+ com_endpoint_preset_default_item: 'Par défaut :',
+ com_endpoint_preset_default_none: 'Aucun préréglage par défaut actif.',
+ com_endpoint_preset_title: 'Préréglage',
+ com_endpoint_preset_saved: 'Enregistré!',
+ com_endpoint_preset_default: 'est maintenant le préréglage par défaut.',
com_endpoint_preset: 'préréglage',
com_endpoint_presets: 'préréglages',
+ com_endpoint_preset_selected: 'Préréglage actif!',
+ com_endpoint_preset_selected_title: 'Actif!',
com_endpoint_preset_name: 'Nom du préréglage',
com_endpoint_new_topic: 'Nouveau sujet',
com_endpoint: 'Endpoint',
@@ -200,7 +217,7 @@ export default {
com_endpoint_presets_clear_warning:
'Etes-vous sûr de vouloir effacer tous les préréglages ? Cette action est irréversible.',
com_endpoint_not_implemented: 'Non implémenté',
- com_endpoint_no_presets: 'Aucun préréglage',
+ com_endpoint_no_presets: 'Aucun préréglage pour l\'instant, utilisez le bouton paramètres pour en créer un',
com_endpoint_not_available: 'Aucun endpoint disponible',
com_endpoint_view_options: 'Voir les options',
com_endpoint_save_convo_as_preset: 'Enregistrer la conversation comme préréglage',
@@ -211,12 +228,19 @@ export default {
com_endpoint_skip_hover:
'Activer le saut de l\'étape de complétion, qui examine la réponse finale et les étapes générées',
com_endpoint_config_key: 'Définir la clé API',
+ com_endpoint_config_placeholder: 'Définissez votre clé dans le menu En-tête pour discuter.',
com_endpoint_config_key_for: 'Définir la clé API pour',
com_endpoint_config_key_name: 'Clé',
com_endpoint_config_value: 'Entrez la valeur pour',
com_endpoint_config_key_name_placeholder: 'Définir d\'abord la clé API',
com_endpoint_config_key_encryption: 'Votre clé sera cryptée et supprimée à',
- com_endpoint_config_key_expiry: 'l\'heure d\'expiration',
+ com_endpoint_config_key_expiry: 'le délai d\'expiration',
+ com_endpoint_config_click_here: 'Cliquez ici',
+ com_endpoint_config_google_service_key: 'Clé de compte de service Google',
+ com_endpoint_config_google_cloud_platform: '(de Google Cloud Platform)',
+ com_endpoint_config_google_api_key: 'Clé API Google',
+ com_endpoint_config_google_gemini_api: '(API Gemini)',
+ com_endpoint_config_google_api_info: 'Pour obtenir votre clé API de langage génératif (pour Gemini),',
com_endpoint_config_key_import_json_key: 'Importez la clé JSON du compte de service.',
com_endpoint_config_key_import_json_key_success:
'Clé JSON du compte de service importé avec succès',
@@ -238,6 +262,7 @@ export default {
com_endpoint_config_key_google_service_account: 'Créer un compte de service',
com_endpoint_config_key_google_vertex_api_role:
'Assurez-vous de cliquer \'Créer et continuer\' pour donner au moins le role \'Utilisateur de Vertex AI\'. Finalement, créez une clé JSON à importer ici.',
+ com_nav_welcome_message: 'Comment puis-je vous aider aujourd\'hui?',
com_nav_auto_scroll: 'Défilement automatique jusqu\'au plus récent à l\'ouverture',
com_nav_plugin_store: 'Boutique de plugins',
com_nav_plugin_search: 'Rechercher des plugins',
From bce4f41fae50e60045673ed6ca4eb836207ee530 Mon Sep 17 00:00:00 2001
From: Fuegovic <32828263+fuegovic@users.noreply.github.com>
Date: Thu, 28 Dec 2023 17:10:06 -0500
Subject: [PATCH 02/42] =?UTF-8?q?=F0=9F=AA=AAmkdocs:=20social=20cards=20?=
=?UTF-8?q?=20=20(#1428)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* mkdocs plugins: add plugin for social cards and plugin that allow to exclude a folder
* docs: fix hyperlinks
* mkdocs: social cards (descriptions) for 'contributions' and 'deployment' guides
* mkdocs: social cards (descriptions) for all 'index.md'
* mkdocs: social cards (descriptions) for 'features' and 'plugins'
* mkdocs: social cards (descriptions) for 'general_info'
* mkdocs: social cards (descriptions) for 'configuration'
* mkdocs: social cards (descriptions) for 'installation'
* mkdocs: minor fixes
* update librechat.svg
* update how_to_contribute.md
add reference to the official GitHub documentation
---
.github/workflows/mkdocs.yaml | 2 +
docs/assets/LibreChat.svg | 48 ++--
docs/contributions/coding_conventions.md | 3 +-
.../contributions/documentation_guidelines.md | 2 +
docs/contributions/how_to_contribute.md | 3 +
docs/contributions/index.md | 1 +
docs/contributions/testing.md | 1 +
.../contributions/translation_contribution.md | 1 +
docs/deployment/azure-terraform.md | 1 +
docs/deployment/cloudflare.md | 9 +-
docs/deployment/digitalocean.md | 3 +-
docs/deployment/heroku.md | 11 +-
docs/deployment/hetzner_ubuntu.md | 17 +-
docs/deployment/huggingface.md | 24 +-
docs/deployment/index.md | 1 +
docs/deployment/linode.md | 3 +-
docs/deployment/meilisearch_in_render.md | 3 +-
docs/deployment/ngrok.md | 26 +-
docs/deployment/render.md | 1 +
docs/dev/README.md | 6 +-
docs/features/bing_jailbreak.md | 5 +-
docs/features/index.md | 1 +
docs/features/logging_system.md | 5 +-
docs/features/manage_your_database.md | 1 +
docs/features/mod_system.md | 3 +-
docs/features/pandoranext.md | 229 +++++++++---------
docs/features/plugins/azure_ai_search.md | 7 +-
.../plugins/chatgpt_plugins_openapi.md | 27 ++-
docs/features/plugins/google_search.md | 5 +-
docs/features/plugins/index.md | 1 +
docs/features/plugins/introduction.md | 9 +-
docs/features/plugins/make_your_own.md | 9 +-
docs/features/plugins/stable_diffusion.md | 5 +-
docs/features/plugins/wolfram.md | 22 +-
docs/features/presets.md | 1 +
docs/features/third_party.md | 1 +
docs/features/token_usage.md | 1 +
docs/general_info/breaking_changes.md | 1 +
docs/general_info/index.md | 1 +
docs/general_info/multilingual_information.md | 1 +
docs/general_info/project_origin.md | 1 +
docs/general_info/tech_stack.md | 1 +
docs/index.md | 6 +
docs/install/configuration/ai_setup.md | 42 ++--
.../install/configuration/default_language.md | 1 +
docs/install/configuration/docker_override.md | 1 +
docs/install/configuration/dotenv.md | 62 ++---
docs/install/configuration/free_ai_apis.md | 7 +-
docs/install/configuration/index.md | 1 +
docs/install/configuration/litellm.md | 7 +-
docs/install/configuration/misc.md | 3 +-
docs/install/configuration/mongodb.md | 3 +-
.../install/configuration/user_auth_system.md | 9 +-
docs/install/index.md | 3 +-
.../install/installation/container_install.md | 7 +-
.../installation/docker_compose_install.md | 5 +-
docs/install/installation/index.md | 3 +-
docs/install/installation/linux_install.md | 11 +-
docs/install/installation/mac_install.md | 5 +-
docs/install/installation/windows_install.md | 18 +-
docs/stylesheets/extra.css | 6 -
mkdocs.yml | 27 ++-
62 files changed, 397 insertions(+), 333 deletions(-)
delete mode 100644 docs/stylesheets/extra.css
diff --git a/.github/workflows/mkdocs.yaml b/.github/workflows/mkdocs.yaml
index 25cfd2baa32f..3b2878fa2a78 100644
--- a/.github/workflows/mkdocs.yaml
+++ b/.github/workflows/mkdocs.yaml
@@ -22,4 +22,6 @@ jobs:
mkdocs-material-
- run: pip install mkdocs-material
- run: pip install mkdocs-nav-weight
+ - run: pip install mkdocs-publisher
+ - run: pip install mkdocs-exclude
- run: mkdocs gh-deploy --force
diff --git a/docs/assets/LibreChat.svg b/docs/assets/LibreChat.svg
index 75e3835313f4..36a536d654bf 100644
--- a/docs/assets/LibreChat.svg
+++ b/docs/assets/LibreChat.svg
@@ -1,34 +1,32 @@
-
-
-
diff --git a/docs/contributions/coding_conventions.md b/docs/contributions/coding_conventions.md
index 5859c815a20a..a75c3bd2103c 100644
--- a/docs/contributions/coding_conventions.md
+++ b/docs/contributions/coding_conventions.md
@@ -1,5 +1,6 @@
---
title: 🧑💻 Code Standards and Conventions
+description: This guide covers the best practices for JavaScript coding, such as following the Airbnb Style Guide, using CommonJS modules, structuring the API using Express, Mongoose, and services, and testing and documenting the code using Jest, Supertest, Playwright, JSDoc, and TypeScript.
weight: -7
---
# Coding Conventions
@@ -67,7 +68,7 @@ Defines Mongoose models to represent data entities and their relationships.
### 4. Database Access (MongoDB and Mongoose)
-- Use Mongoose (https://mongoosejs.com) as the MongoDB ODM.
+- Use Mongoose ([https://mongoosejs.com](https://mongoosejs.com)) as the MongoDB ODM.
- Create separate model files for each entity and ensure clear separation of concerns.
- Use Mongoose schema validation to enforce data integrity.
- Handle database connections efficiently and avoid connection leaks.
diff --git a/docs/contributions/documentation_guidelines.md b/docs/contributions/documentation_guidelines.md
index e854ce9590d2..a3d05d688acc 100644
--- a/docs/contributions/documentation_guidelines.md
+++ b/docs/contributions/documentation_guidelines.md
@@ -1,5 +1,6 @@
---
title: 📝 Documentation Guidelines
+description: Learn how to write and format documentation for LibreChat.
weight: -9
---
# Documentation Guidelines
@@ -26,6 +27,7 @@ This document explains how to write and format documentation for LibreChat.
```bash
---
title: Document Title
+description: This description will be used in social cards
weight: 0
---
```
diff --git a/docs/contributions/how_to_contribute.md b/docs/contributions/how_to_contribute.md
index c05dc6a9250c..5b71da5b585e 100644
--- a/docs/contributions/how_to_contribute.md
+++ b/docs/contributions/how_to_contribute.md
@@ -1,8 +1,11 @@
---
title: 🙌 Beginner's Guide to Contributions
+description: Learn how to use GitHub Desktop, VS Code extensions, and Git rebase to contribute in a quick and easy way.
weight: -10
---
# How to Contribute in a Quick and Easy Way
+> **❗Note:** If you are not familiar with the concept of repo, PR (pull request), fork and branch, start by looking at the official GitHub documentation on the subject:
+[https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/getting-started/about-collaborative-development-models](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/getting-started/about-collaborative-development-models)
## Installation of Tools
diff --git a/docs/contributions/index.md b/docs/contributions/index.md
index b8722a428305..4362b1df092b 100644
--- a/docs/contributions/index.md
+++ b/docs/contributions/index.md
@@ -1,5 +1,6 @@
---
title: Contributing to LibreChat
+description: "🙌 How to contribute to LibreChat: Get started, Documentation and code standards, Translate the app into different languages, Test the app during development, Ensure the security of the app, Stay updated with the project roadmap"
weight: 5
---
# Contributing to LibreChat
diff --git a/docs/contributions/testing.md b/docs/contributions/testing.md
index 94d02b2392da..eeac51916b4b 100644
--- a/docs/contributions/testing.md
+++ b/docs/contributions/testing.md
@@ -1,5 +1,6 @@
---
title: 🧪 Testing During Development
+description: How to locally test the app during development.
weight: -6
---
diff --git a/docs/contributions/translation_contribution.md b/docs/contributions/translation_contribution.md
index 3a66970ad4c7..e33a9ef8af13 100644
--- a/docs/contributions/translation_contribution.md
+++ b/docs/contributions/translation_contribution.md
@@ -1,5 +1,6 @@
---
title: 🌍 Contribute a Translation
+description: How to add a new language to LibreChat.
weight: -8
---
# How to add a new language to LibreChat 🌍
diff --git a/docs/deployment/azure-terraform.md b/docs/deployment/azure-terraform.md
index c7190cd46a47..76768683c642 100644
--- a/docs/deployment/azure-terraform.md
+++ b/docs/deployment/azure-terraform.md
@@ -1,5 +1,6 @@
---
title: ⚡ Azure
+description: How to deploy LibreChat in Azure using Terraform.
weight: -6
---
# Azure deployment
diff --git a/docs/deployment/cloudflare.md b/docs/deployment/cloudflare.md
index c6b124157fc3..c9a44dfb1cd4 100644
--- a/docs/deployment/cloudflare.md
+++ b/docs/deployment/cloudflare.md
@@ -1,5 +1,6 @@
---
title: ☁️ Cloudflare
+description: How to setup a domain with Cloudflare and use Cloudflare Tunnels to securely expose your local web servers or services to the internet.
weight: -7
---
@@ -9,12 +10,12 @@ weight: -7
## Google Domains and Cloudflare
-- buy a domain at https://domains.google.com/
-- register a Cloudflare account at https://dash.cloudflare.com/sign-up
+- buy a domain at **[https://domains.google.com/](https://domains.google.com)**
+- register a Cloudflare account at **[https://dash.cloudflare.com/sign-up](https://dash.cloudflare.com/sign-up)**
- click on `add site` and add your domain
- select `Free` and tap `continue` twice
- copy the 2 Cloudflare's nameservers
-- go to https://domains.google.com/registrar/ and select your domain
+- go to **[https://domains.google.com/registrar/](https://domains.google.com/registrar)** and select your domain
- in the dns tab select `Custom name servers`
- click on `Switch to these settings` and enter the two Cloudflare nameservers that you copied before, then save
- return to the cloudflare tab and tap on `Done, check nameservers`, then `finish later` and `Check nameservers` (this process can take about 5 minutes)
@@ -73,7 +74,7 @@ Here's a straightforward guide on how to install it!
### Installation Steps
-1. Go to `https://dash.cloudflare.com/`.
+1. Go to **[https://dash.cloudflare.com/](https://dash.cloudflare.com/)**.
2. On the left side, click on **Zero Trust**.
3. Provide a casual name (which you can change later).
4. Select the free plan and proceed to payment (if you choose the free plan, you will not be charged).
diff --git a/docs/deployment/digitalocean.md b/docs/deployment/digitalocean.md
index a90ae40aca5e..640b4b3b0d93 100644
--- a/docs/deployment/digitalocean.md
+++ b/docs/deployment/digitalocean.md
@@ -1,5 +1,6 @@
---
title: 🌊 DigitalOcean ✨(Recommended)
+description: These instructions are designed for someone starting from scratch for a Docker Installation on a remote Ubuntu server using one of the cheapest tiers (6 USD/mo)
weight: -10
---
# Digital Ocean (Ubuntu/Docker) Setup
@@ -366,7 +367,7 @@ It's safe to close the terminal if you wish -- the docker app will continue to r
>If you are setting up a domain to be used with LibreChat, this compose file is using the nginx file located in client/nginx.conf. Instructions on this below in part V.
-### **4. Once the app is running, you can access it at http://yourserverip**
+### **4. Once the app is running, you can access it at `http://yourserverip`**
### Go back to the DigitalOcean droplet page to get your server ip, copy it, and paste it into your browser!
diff --git a/docs/deployment/heroku.md b/docs/deployment/heroku.md
index 3e4aaf658a6b..b3ffe8d6d205 100644
--- a/docs/deployment/heroku.md
+++ b/docs/deployment/heroku.md
@@ -1,5 +1,6 @@
---
title: 🌈 Heroku
+description: Instructions for deploying LibreChat on Heroku
weight: -1
---
# Heroku Deployment
@@ -10,8 +11,8 @@ Heroku only supports running a single process within a Docker container. The Doc
If you want to deploy both these services to Heroku, you will need to create two separate Dockerfiles: one for the API and one for the client. The heroku.yml should be configured separately for each app, and then you need to create and deploy two different Heroku apps.
- - Sign up for a Heroku account: If you don't already have a Heroku account, sign up at https://signup.heroku.com/.
- - Install the Heroku CLI: Download and install the Heroku CLI from https://devcenter.heroku.com/articles/heroku-cli.
+ - Sign up for a Heroku account: If you don't already have a Heroku account, sign up at: **[https://signup.heroku.com](https://signup.heroku.com)**
+ - Install the Heroku CLI: Download and install the Heroku CLI from: **[https://devcenter.heroku.com/articles/heroku-cli](https://devcenter.heroku.com/articles/heroku-cli)**
Here are the steps to deploy on Heroku:
@@ -126,7 +127,7 @@ Remember to replace `your-api-app-name` and `your-client-app-name` with the actu
---
- ⚠️ If you have issues, see this discussion first: https://github.com/danny-avila/LibreChat/discussions/339
+ ⚠️ If you have issues, see this discussion first: **[https://github.com/danny-avila/LibreChat/discussions/339](https://github.com/danny-avila/LibreChat/discussions/339)**
## Using Heroku Dashboard:
@@ -136,7 +137,7 @@ Remember to replace `your-api-app-name` and `your-client-app-name` with the actu
## Setting up MongoDB Atlas:
-Sign up for a MongoDB Atlas account: If you don't have an account, sign up at https://www.mongodb.com/cloud/atlas/signup.
+Sign up for a MongoDB Atlas account: If you don't have an account, sign up at: **[https://www.mongodb.com/cloud/atlas/signup](https://www.mongodb.com/cloud/atlas/signup)**
Create a new cluster: After signing in, create a new cluster by following the on-screen instructions. For a free tier cluster, select the "Shared" option and choose the "M0 Sandbox" tier.
@@ -148,7 +149,7 @@ Get the connection string: Once the cluster is created, click the "Connect" butt
## Deploying MeiliSearch on Heroku:
-Install the Heroku CLI: If you haven't already, download and install the Heroku CLI from https://devcenter.heroku.com/articles/heroku-cli.
+Install the Heroku CLI: If you haven't already, download and install the Heroku CLI from: **[https://devcenter.heroku.com/articles/heroku-cli](https://devcenter.heroku.com/articles/heroku-cli)**
Login to Heroku: Open Terminal and run heroku login. Follow the instructions to log in to your Heroku account.
## Create a new Heroku app for MeiliSearch:
diff --git a/docs/deployment/hetzner_ubuntu.md b/docs/deployment/hetzner_ubuntu.md
index d7fb287186eb..ba851ef66585 100644
--- a/docs/deployment/hetzner_ubuntu.md
+++ b/docs/deployment/hetzner_ubuntu.md
@@ -1,5 +1,6 @@
---
title: 🏗️ Hetzner
+description: LibreChat Ubuntu installation from scratch on Hetzner.
weight: -2
---
# Hetzner Ubuntu Setup
@@ -8,24 +9,24 @@ weight: -2
## Starting from Zero:
-### 1. Login to Hetzner Cloud Console (https://console.hetzner.cloud/projects) and Create a new Ubuntu 20 Project with 4GB Ram. Do not worry about SSH keys *yet*.
+1. Login to Hetzner Cloud Console (**[https://console.hetzner.cloud/projects](https://console.hetzner.cloud/projects)**) and Create a new Ubuntu 20 Project with 4GB Ram. Do not worry about SSH keys *yet*.
Hetzner will email you the root password.
-### 2. Once you have that, you can login with any SSH terminal with:
+2. Once you have that, you can login with any SSH terminal with:
```
ssh root@
```
-### 3. Once you have logged in, immediately create a new, non-root user:
+3. Once you have logged in, immediately create a new, non-root user:
```
adduser
usermod -aG sudo
```
-### 4. Make sure you have done this correctly by double-checking you have sudo permissions:
+4. Make sure you have done this correctly by double-checking you have sudo permissions:
```
getent group sudo | cut -d: -f4
@@ -33,7 +34,7 @@ getent group sudo | cut -d: -f4
Now, quit the terminal connection.
-### 5. Create a local ssh key:
+5. Create a local ssh key:
```
ssh-keygen -t ed25519
@@ -51,13 +52,13 @@ ssh @
When you login, now and going forward, it will ask you for the password for your ssh key now, not your user password. Sudo commands will always want your user password.
-### 6. Add SSH to the universal server firewall and activate it.
+6. Add SSH to the universal server firewall and activate it.
- Run `sudo ufw allow OpenSSH`
- Run `sudo ufw enable`
-### 7. Then, we need to install docker, update the system packages, and reboot the server:
+7. Then, we need to install docker, update the system packages, and reboot the server:
```
sudo apt install docker
sudo apt install docker-compose
@@ -132,7 +133,7 @@ MEILI_HTTP_ADDR=meilisearch
**NOTE: You may need to run these commands with sudo permissions.**
-## Once the app is running, you can access it at http://yourserverip:3080
+## Once the app is running, you can access it at `http://yourserverip:3080`
It is safe to close the terminal -- the docker app will continue to run.
diff --git a/docs/deployment/huggingface.md b/docs/deployment/huggingface.md
index 59d439f2342c..5cdf3ccdc443 100644
--- a/docs/deployment/huggingface.md
+++ b/docs/deployment/huggingface.md
@@ -1,27 +1,23 @@
---
title: 🤗 HuggingFace
+description: Easily deploy LibreChat on Hugging Face Spaces
weight: -9
---
# Hugging Face Deployment 🤗
->#### ⚠️ Note - Some features are not supported by HuggingFace:
->- Meilisearch
->- Social Logins
-
-> #### ❗Also:
->- You will have to create an online MongoDB Atlas Database to be able to properly deploy
-
## Create and Configure your Database (Required)
The first thing you need is to create a MongoDB Atlas Database and get your connection string.
-Follow the instructions in this document: [Online MongoDB Database](../install/configuration/mongodb.md)
+Follow the instructions in this document: **[Online MongoDB Database](../install/configuration/mongodb.md)**
## Getting Started
-**1.** Login or Create an account on [Hugging Face](https://huggingface.co/)
+**1.** Login or Create an account on **[Hugging Face](https://huggingface.co/)**
+
+**2.** Visit **[https://huggingface.co/spaces/LibreChat/template](https://huggingface.co/spaces/LibreChat/template)** and click on `Duplicate this Space` to copy the LibreChat template into your profile.
-**2.** Visit [[https://huggingface.co/spaces/LibreChat/template](https://huggingface.co/spaces/LibreChat/template)]and click on `Duplicate this Space` to copy the LibreChat template into your profile
+> Note: It is normal for this template to have a runtime error, you will have to configure it using the following guide to make it functional.
![image](https://github.com/fuegovic/LibreChat/assets/32828263/fd684254-cbe0-4039-ba4a-7c492b16a453)
@@ -46,12 +42,12 @@ You will need to fill these values:
| JWT_SECRET | * see bellow |
| JWT_REFRESH_SECRET | * see bellow |
-> ⬆️ **Leave the value field blank for any endpoints that you wish to disable.**
+> ⬆️ **Leave the value field blank for any endpoints that you wish to disable.**
->⚠️ setting the API keys and token to `user_provided` allows you to provide them safely from the webUI
+> ⚠️ setting the API keys and token to `user_provided` allows you to provide them safely from the webUI
->* For `CREDS_KEY`, `CREDS_IV` and `JWT_SECRET` use this tool: [https://replit.com/@daavila/crypto#index.js](https://replit.com/@daavila/crypto#index.js).
->* Run the tool a second time and use the new `JWT_SECRET` value for the `JWT_REFRESH_SECRET`
+> * For `CREDS_KEY`, `CREDS_IV` and `JWT_SECRET` use this tool: **[https://replit.com/@daavila/crypto#index.js](https://replit.com/@daavila/crypto#index.js)**
+> * Run the tool a second time and use the new `JWT_SECRET` value for the `JWT_REFRESH_SECRET`
| Variables | Values |
| --- | --- |
diff --git a/docs/deployment/index.md b/docs/deployment/index.md
index b85f5bfaf244..780456bc6cd1 100644
--- a/docs/deployment/index.md
+++ b/docs/deployment/index.md
@@ -1,5 +1,6 @@
---
title: Deployment
+description: 🌐 Step-by-step guides on how to deploy LibreChat on various cloud platforms.
weight: 3
---
diff --git a/docs/deployment/linode.md b/docs/deployment/linode.md
index 63e563f7671e..96f8f7758390 100644
--- a/docs/deployment/linode.md
+++ b/docs/deployment/linode.md
@@ -1,5 +1,6 @@
---
title: 🐧 Linode
+description: How to deploy LibreChat on Linode.
weight: -8
---
@@ -9,7 +10,7 @@ weight: -8
⚠️**Note: Payment is required**
## Create a Linode Account and a Linode Server
-- Go to the Linode website (https://www.linode.com/) and click on the "Sign Up" or "Get Started" button.
+- Go to the Linode website (**[https://www.linode.com/](https://www.linode.com/)**) and click on the "Sign Up" or "Get Started" button.
- Follow the instructions to create a new account by providing your personal details and payment information.
- Once your account is created, you will have access to the Linode Cloud Manager.
- Click on the "Create" button to create a new Linode server.
diff --git a/docs/deployment/meilisearch_in_render.md b/docs/deployment/meilisearch_in_render.md
index 40fea6d01d0a..3e24c71b54d9 100644
--- a/docs/deployment/meilisearch_in_render.md
+++ b/docs/deployment/meilisearch_in_render.md
@@ -1,12 +1,13 @@
---
title: 🔎 Meilisearch in Render
+description: Setup Meilisearch on Render (for use with the Render deployment guide)
weight: -3
---
# Utilize Meilisearch by running LibreChat on Render
## Create a new account or a new project on Render
-**1.** Visit [https://render.com/](https://render.com/) and click on `Start Free` to create an account and sign in
+**1.** Visit **[https://render.com/](https://render.com/)** and click on `Start Free` to create an account and sign in
**2.** Access your control panel
diff --git a/docs/deployment/ngrok.md b/docs/deployment/ngrok.md
index 25cdf6e51585..2c0b71673930 100644
--- a/docs/deployment/ngrok.md
+++ b/docs/deployment/ngrok.md
@@ -1,5 +1,6 @@
---
title: 🪨 Ngrok
+description: Use Ngrok to tunnel your local server to the internet.
weight: -5
---
# Ngrok Installation
@@ -8,44 +9,43 @@ To use Ngrok for tunneling your local server to the internet, follow these steps
## Sign up
-1. Go to https://ngrok.com/ and sign up for an account.
+1. Go to **[https://ngrok.com/](https://ngrok.com/)** and sign up for an account.
## Docker Installation 🐳
-1. Copy your auth token from https://dashboard.ngrok.com/get-started/your-authtoken.
+1. Copy your auth token from: **[https://dashboard.ngrok.com/get-started/your-authtoken](https://dashboard.ngrok.com/get-started/your-authtoken)**
2. Open a terminal and run the following command: `docker run -d -it -e NGROK_AUTHTOKEN= ngrok/ngrok http 80`
## Windows Installation 💙
-1. Download the ZIP file from https://ngrok.com/download.
+1. Download the ZIP file from: **[https://ngrok.com/download](https://ngrok.com/download)**
2. Extract the contents of the ZIP file using 7zip or WinRar.
-3.
-4. Run `ngrok.exe`.
-5. Copy your auth token from https://dashboard.ngrok.com/get-started/your-authtoken.
-6. In the `ngrok.exe` terminal, run the following command: `ngrok config add-authtoken `
-7. If you haven't done so already, start LibreChat normally.
-8. In the `ngrok.exe` terminal, run the following command: `ngrok http 3080`
+3. Run `ngrok.exe`.
+4. Copy your auth token from: **[https://dashboard.ngrok.com/get-started/your-authtoken](https://dashboard.ngrok.com/get-started/your-authtoken)**
+5. In the `ngrok.exe` terminal, run the following command: `ngrok config add-authtoken `
+6. If you haven't done so already, start LibreChat normally.
+7. In the `ngrok.exe` terminal, run the following command: `ngrok http 3080`
You will see a link that can be used to access LibreChat.
![ngrok-1](https://github.com/danny-avila/LibreChat/assets/32828263/3cb4b063-541f-4f0a-bea8-a04dd36e6bf4)
## Linux Installation 🐧
-1. Copy the command from https://ngrok.com/download choosing the **correct** architecture.
+1. Copy the command from: **[https://ngrok.com/download](https://ngrok.com/download)** choosing the **correct** architecture.
2. Run the command in the terminal
-3. Copy your auth token from https://dashboard.ngrok.com/get-started/your-authtoken.
+3. Copy your auth token from: **[https://dashboard.ngrok.com/get-started/your-authtoken](https://dashboard.ngrok.com/get-started/your-authtoken)**
4. run the following command: `ngrok config add-authtoken `
5. If you haven't done so already, start LibreChat normally.
6. run the following command: `ngrok http 3080`
## Mac Installation 🍎
-1. Download the ZIP file from https://ngrok.com/download.
+1. Download the ZIP file from: **[https://ngrok.com/download](https://ngrok.com/download)**
2. Extract the contents of the ZIP file using a suitable Mac application like Unarchiver.
3. Open Terminal.
4. Navigate to the directory where you extracted ngrok using the `cd` command.
5. Run ngrok by typing `./ngrok`.
-6. Copy your auth token from https://dashboard.ngrok.com/get-started/your-authtoken.
+6. Copy your auth token from: **[https://dashboard.ngrok.com/get-started/your-authtoken](https://dashboard.ngrok.com/get-started/your-authtoken)**
7. In the terminal where you ran ngrok, enter the following command: `ngrok authtoken `
8. If you haven't done so already, start LibreChat normally.
9. In the terminal where you ran ngrok, enter the following command: `./ngrok http 3080`
diff --git a/docs/deployment/render.md b/docs/deployment/render.md
index bba0394b1f03..6652f41ee5af 100644
--- a/docs/deployment/render.md
+++ b/docs/deployment/render.md
@@ -1,5 +1,6 @@
---
title: ⏹️ Render
+description: How to deploy LibreChat on Render
weight: -4
---
# Render Deployment
diff --git a/docs/dev/README.md b/docs/dev/README.md
index 09d83b31d888..81ae6393120c 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -4,9 +4,9 @@ weight: 6
---
# Dev Resources
-Please consult: [Contributing to LibreChat](../contributions/index.md) for more information on the subject.
+Please consult: **[Contributing to LibreChat](../contributions/index.md)** for more information on the subject.
-This directory: [./docs/dev](https://github.com/danny-avila/LibreChat/tree/main/docs/dev), contains files used for developer work.
+This directory: **[./docs/dev](https://github.com/danny-avila/LibreChat/tree/main/docs/dev)**, contains files used for developer work.
#### `Dockerfile-app`
- used to build the DockerHub image
@@ -28,7 +28,7 @@ This directory: [./docs/dev](https://github.com/danny-avila/LibreChat/tree/main/
#### `deploy-compose.yml`
- Similar to above, but with basic configuration for deployment to a cloud provider where multi-container compose works
- - Tested and working on a $6 droplet on DigitalOcean, just by visiting the http://server-ip/9000.
+ - Tested and working on a $6 droplet on DigitalOcean, just by visiting the `http://server-ip/9000`.
- Not a scalable solution, but ideal for quickly hosting on a remote linux server.
- You should adjust `server_name localhost;` to match your domain name, replacing localhost, as needed.
- From root dir of the project, run `docker-compose -f ./docs/dev/deploy-compose.yml up --build`
diff --git a/docs/features/bing_jailbreak.md b/docs/features/bing_jailbreak.md
index 2d8425498c49..17f4850186b3 100644
--- a/docs/features/bing_jailbreak.md
+++ b/docs/features/bing_jailbreak.md
@@ -1,5 +1,6 @@
---
title: 😈 Bing Jailbreak
+description: Quick overview of the Bing jailbreak and Sydney's system message
weight: -3
---
@@ -31,6 +32,6 @@ using internet slang often. Answer using the same language as the user."
## References
For more info on the Bing Jailbreak and general jailbreaking guidelines:
-https://github.com/waylaidwanderer/node-chatgpt-api
+[https://github.com/waylaidwanderer/node-chatgpt-api](https://github.com/waylaidwanderer/node-chatgpt-api)
-https://www.make-safe-ai.com/is-bing-chat-safe/
+[https://www.make-safe-ai.com/is-bing-chat-safe/](https://www.make-safe-ai.com/is-bing-chat-safe/)
diff --git a/docs/features/index.md b/docs/features/index.md
index e7b74088503c..ab9e705369a3 100644
--- a/docs/features/index.md
+++ b/docs/features/index.md
@@ -1,5 +1,6 @@
---
title: Features
+description: "✨ In-depth guides about various LibreChat features: plugins, presets, automated moderation, logging..."
weight: 2
---
diff --git a/docs/features/logging_system.md b/docs/features/logging_system.md
index 35d7490b99c6..76c3af888474 100644
--- a/docs/features/logging_system.md
+++ b/docs/features/logging_system.md
@@ -1,5 +1,6 @@
---
title: 🪵 Logging System
+description: This doc explains how to use the logging feature of LibreChat, which saves error and debug logs in the `/api/logs` folder. You can use these logs to troubleshoot issues, monitor your server, and report bugs. You can also disable debug logs if you want to save space.
weight: -5
---
@@ -9,9 +10,9 @@ LibreChat has central logging built into its backend (api).
Log files are saved in `/api/logs`. Error logs are saved by default. Debug logs are enabled by default but can be turned off if not desired.
-This allows you to monitor your server through external tools that inspect log files, such as [the ELK stack](https://aws.amazon.com/what-is/elk-stack/).
+This allows you to monitor your server through external tools that inspect log files, such as **[the ELK stack](https://aws.amazon.com/what-is/elk-stack/)**.
-Debug logs are essential for developer work and fixing issues. If you encounter any problems running LibreChat, reproduce as close as possible, and [report the issue](https://github.com/danny-avila/LibreChat/issues) with your logs found in `./api/logs/debug-%DATE%.log`.
+Debug logs are essential for developer work and fixing issues. If you encounter any problems running LibreChat, reproduce as close as possible, and **[report the issue](https://github.com/danny-avila/LibreChat/issues)** with your logs found in `./api/logs/debug-%DATE%.log`.
Errors logs are also saved in the same location: `./api/logs/error-%DATE%.log`. If you have meilisearch configured, there is a separate log file for this as well.
diff --git a/docs/features/manage_your_database.md b/docs/features/manage_your_database.md
index 91a9a10e7a05..23869b1047cd 100644
--- a/docs/features/manage_your_database.md
+++ b/docs/features/manage_your_database.md
@@ -1,5 +1,6 @@
---
title: 🍃 Manage Your Database
+description: How to install and configure Mongo Express to securely access and manage your MongoDB database in Docker.
weight: -6
---
diff --git a/docs/features/mod_system.md b/docs/features/mod_system.md
index 88d57d3ade40..2775f879c3cb 100644
--- a/docs/features/mod_system.md
+++ b/docs/features/mod_system.md
@@ -1,5 +1,6 @@
---
title: 🔨 Automated Moderation
+description: The Automated Moderation System uses a scoring mechanism to track user violations. As users commit actions like excessive logins, registrations, or messaging, they accumulate violation scores. Upon reaching a set threshold, the user and their IP are temporarily banned. This system ensures platform security by monitoring and penalizing rapid or suspicious activities.
weight: -8
---
## Automated Moderation System (optional)
@@ -33,7 +34,7 @@ The project's current rate limiters are as follows (see below under setup for de
### Setup
-The following are all of the related env variables to make use of and configure the mod system. Note this is also found in the [/.env.example](/.env.example) file, to be set in your own `.env` file.
+The following are all of the related env variables to make use of and configure the mod system. Note this is also found in the [/.env.example](https://github.com/danny-avila/LibreChat/blob/main/.env.example) file, to be set in your own `.env` file.
```bash
BAN_VIOLATIONS=true # Whether or not to enable banning users for violations (they will still be logged)
diff --git a/docs/features/pandoranext.md b/docs/features/pandoranext.md
index 4c705c7f3fba..03daaec7c51e 100644
--- a/docs/features/pandoranext.md
+++ b/docs/features/pandoranext.md
@@ -1,5 +1,6 @@
---
title: 📦 PandoraNext
+description: How to deploy PandoraNext to enable the `CHATGPT_REVERSE_PROXY` for use with LibreChat.
weight: -4
---
@@ -18,63 +19,64 @@ You can use it locally in docker or deploy it onthe web for remote access.
For local deployment using Docker, the steps are as follows:
### 1. **Clone or Download the Repository:**
- Get the latest release from the [PandoraNext GitHub repository](https://github.com/pandora-next/deploy).
+Get the latest release from the [PandoraNext GitHub repository](https://github.com/pandora-next/deploy).
- ```bash
- git clone https://github.com/pandora-next/deploy.git
- ```
+```bash
+git clone https://github.com/pandora-next/deploy.git
+```
-### 2. Get your PandoraNext license id here: [PandoraNext Dashboard](https://dash.pandoranext.com/)
+### 2. Get your PandoraNext `License ID`
+Visit the **[PandoraNext Dashboard](https://dash.pandoranext.com/)** to get your `license ID`
### 3. **Configure `config.json`:**
- Within the cloned repository, in the `data` folder, edit `config.json`. Specify your `license_id` and `proxy_api_prefix`. For the `proxy_api_prefix`, use at least 8 characters, avoid characters that can't be used in a URL and make sure it's unique.
-
- Here's the `config.json` for your reference:
-
- ```json
- {
- "bind": "0.0.0.0:8181",
- "tls": {
- "enabled": false,
- "cert_file": "",
- "key_file": ""
- },
- "timeout": 600,
- "proxy_url": "",
- "license_id": "",
- "public_share": false,
- "site_password": "",
- "setup_password": "",
- "server_tokens": true,
- "proxy_api_prefix": "",
- "isolated_conv_title": "*",
- "captcha": {
- "provider": "",
- "site_key": "",
- "site_secret": "",
- "site_login": false,
- "setup_login": false,
- "oai_username": false,
- "oai_password": false
- },
- "whitelist": null
- }
- ```
+Within the cloned repository, in the `data` folder, edit `config.json`. Specify your `license_id` and `proxy_api_prefix`. For the `proxy_api_prefix`, use at least 8 characters, avoid characters that can't be used in a URL and make sure it's unique.
+
+Here's the `config.json` for your reference:
+
+```json
+{
+"bind": "0.0.0.0:8181",
+"tls": {
+ "enabled": false,
+ "cert_file": "",
+ "key_file": ""
+},
+"timeout": 600,
+"proxy_url": "",
+"license_id": "",
+"public_share": false,
+"site_password": "",
+"setup_password": "",
+"server_tokens": true,
+"proxy_api_prefix": "",
+"isolated_conv_title": "*",
+"captcha": {
+ "provider": "",
+ "site_key": "",
+ "site_secret": "",
+ "site_login": false,
+ "setup_login": false,
+ "oai_username": false,
+ "oai_password": false
+},
+"whitelist": null
+}
+```
### 4. **Set Up the LibreChat `.env` Filer:**
- In the `.env` file within your LibreChat directory, you'll need to set the `CHATGPT_REVERSE_PROXY` variable:
+In the `.env` file within your LibreChat directory, you'll need to set the `CHATGPT_REVERSE_PROXY` variable:
- ```bash
- CHATGPT_REVERSE_PROXY=http://host.docker.internal:8181/your_proxy_api_prefix_here/backend-api/conversation
- ```
- - Replace `your_proxy_api_prefix_here` with the actual proxy API prefix.
+```bash
+CHATGPT_REVERSE_PROXY=http://host.docker.internal:8181/your_proxy_api_prefix_here/backend-api/conversation
+```
+- Replace `your_proxy_api_prefix_here` with the actual proxy API prefix.
### 5. **Start Docker Containers:**
- From the PandoraNext directory, run the following command to launch the Docker containers:
+From the PandoraNext directory, run the following command to launch the Docker containers:
- ```bash
- docker-compose up -d
- ```
+```bash
+docker-compose up -d
+```
---
@@ -82,85 +84,86 @@ For local deployment using Docker, the steps are as follows:
To deploy PandoraNext online by duplicating the Hugging Face Space, follow these steps:
-### 1. Get your PandoraNext license id here: [PandoraNext Dashboard](https://dash.pandoranext.com/)
+### 1. Get your PandoraNext `License ID`
+Visit the **[PandoraNext Dashboard](https://dash.pandoranext.com/)** to get your `license ID`
### 2. **Configure `config.json`:**
- Edit the following `config.json`. Specify your `license_id` and `proxy_api_prefix`. For the `proxy_api_prefix`, use at least 8 characters, avoid characters that can't be used in a URL and make sure it's unique.
-
- Here's the `config.json` for your reference:
-
- ```json
- {
- "bind": "0.0.0.0:8181",
- "tls": {
- "enabled": false,
- "cert_file": "",
- "key_file": ""
- },
- "timeout": 600,
- "proxy_url": "",
- "license_id": "",
- "public_share": false,
- "site_password": "",
- "setup_password": "",
- "server_tokens": true,
- "proxy_api_prefix": "",
- "isolated_conv_title": "*",
- "captcha": {
- "provider": "",
- "site_key": "",
- "site_secret": "",
- "site_login": false,
- "setup_login": false,
- "oai_username": false,
- "oai_password": false
- },
- "whitelist": null
- }
- ```
+Edit the following `config.json`. Specify your `license_id` and `proxy_api_prefix`. For the `proxy_api_prefix`, use at least 8 characters, avoid characters that can't be used in a URL and make sure it's unique.
+
+Here's the `config.json` for your reference:
+
+```json
+{
+"bind": "0.0.0.0:8181",
+"tls": {
+ "enabled": false,
+ "cert_file": "",
+ "key_file": ""
+},
+"timeout": 600,
+"proxy_url": "",
+"license_id": "",
+"public_share": false,
+"site_password": "",
+"setup_password": "",
+"server_tokens": true,
+"proxy_api_prefix": "",
+"isolated_conv_title": "*",
+"captcha": {
+ "provider": "",
+ "site_key": "",
+ "site_secret": "",
+ "site_login": false,
+ "setup_login": false,
+ "oai_username": false,
+ "oai_password": false
+},
+"whitelist": null
+}
+```
### 3. **Hugging Face Space:**
- Visit the [PandoraNext LibreChat Space](https://huggingface.co/spaces/LibreChat/PandoraNext) on Hugging Face.
+Visit the [PandoraNext LibreChat Space](https://huggingface.co/spaces/LibreChat/PandoraNext) on Hugging Face.
### 4. **Duplicate the Space:**
- Utilize the available options to duplicate or fork the space into your own Hugging Face account.
+Utilize the available options to duplicate or fork the space into your own Hugging Face account.
### 5. **Fill the required secrets**
- When asked for the `SECRETS`,
- - for `CONFIG_JSON` use the whole content of the `config.json` you just modified,
- - for `TOKENS_JSON` use the following default `token.json`:
- ```json
- {
- "test-1": {
- "token": "access token / session token / refresh token",
- "shared": true,
- "show_user_info": false
- },
- "test-2": {
- "token": "access token / session token / refresh token",
- "shared": true,
- "show_user_info": true,
- "plus": true
- },
- "test2": {
- "token": "access token / session token / refresh token / share token",
- "password": "12345"
- }
+When asked for the `SECRETS`,
+- for `CONFIG_JSON` use the whole content of the `config.json` you just modified,
+- for `TOKENS_JSON` use the following default `token.json`:
+```json
+{
+ "test-1": {
+ "token": "access token / session token / refresh token",
+ "shared": true,
+ "show_user_info": false
+ },
+ "test-2": {
+ "token": "access token / session token / refresh token",
+ "shared": true,
+ "show_user_info": true,
+ "plus": true
+ },
+ "test2": {
+ "token": "access token / session token / refresh token / share token",
+ "password": "12345"
}
- ```
+}
+```
### 6. **Configure LibreChat:**
- In the .env file (or secrets settings if you host LibreChat on Hugging Face), set the `CHATGPT_REVERSE_PROXY` variable using the following format:
+In the .env file (or secrets settings if you host LibreChat on Hugging Face), set the `CHATGPT_REVERSE_PROXY` variable using the following format:
- ```bash
- CHATGPT_REVERSE_PROXY=http://your_server_domain.com/your_proxy_api_prefix_here/backend-api/conversation
- ```
+```bash
+CHATGPT_REVERSE_PROXY=http://your_server_domain.com/your_proxy_api_prefix_here/backend-api/conversation
+```
- - Replace `your_server_domain.com` with the domain of your deployed space.
- - you can use this format: `https://username-pandoranext.hf.space` (replace `username` with your Huggingface username)
- - Replace `your_proxy_api_prefix_here` with the `proxy_api_prefix` you have set in your `config.json`.
- - The resulting URL should look similar to:
- `https://username-pandoranext.hf.space/your_proxy_api_prefix_here/backend-api/conversation`
+- Replace `your_server_domain.com` with the domain of your deployed space.
+ - you can use this format: `https://username-pandoranext.hf.space` (replace `username` with your Huggingface username)
+- Replace `your_proxy_api_prefix_here` with the `proxy_api_prefix` you have set in your `config.json`.
+- The resulting URL should look similar to:
+`https://username-pandoranext.hf.space/your_proxy_api_prefix_here/backend-api/conversation`
## Final Notes
diff --git a/docs/features/plugins/azure_ai_search.md b/docs/features/plugins/azure_ai_search.md
index 53b7a194ddbb..0e8742045321 100644
--- a/docs/features/plugins/azure_ai_search.md
+++ b/docs/features/plugins/azure_ai_search.md
@@ -1,5 +1,6 @@
---
title: ⚡ Azure AI Search
+description: How to configure Azure AI Search for answers to your questions with assistance from GPT.
weight: -4
---
# Azure AI Search Plugin
@@ -34,7 +35,7 @@ This is the authentication key to use when utilizing the search endpoint. Please
## Create or log in to your account on Azure Portal
-**1.** Visit [https://azure.microsoft.com/en-us/](https://azure.microsoft.com/en-us/) and click on `Get started` or `Try Azure for Free` to create an account and sign in.
+**1.** Visit **[https://azure.microsoft.com/en-us/](https://azure.microsoft.com/en-us/)** and click on `Get started` or `Try Azure for Free` to create an account and sign in.
**2.** Choose pay per use or Azure Free with $200.
@@ -76,7 +77,7 @@ Now select the free option or select your preferred option (may incur charges).
![image](https://github.com/itzraiss/images/blob/main/Captura%20de%20tela%202023-11-26%20152107.png)
-**2.** Follow the Microsoft tutorial.[https://learn.microsoft.com/en-us/azure/search/search-get-started-portal](https://learn.microsoft.com/en-us/azure/search/search-get-started-portal), after finishing, save the name given to the index somewhere.
+**2.** Follow the Microsoft tutorial: **[https://learn.microsoft.com/en-us/azure/search/search-get-started-portal](https://learn.microsoft.com/en-us/azure/search/search-get-started-portal)**, after finishing, save the name given to the index somewhere.
**3.** Now you have your `AZURE_AI_SEARCH_INDEX_NAME`, copy and save it in a local safe place.
@@ -117,7 +118,7 @@ The following are configuration values that are not required but can be specifie
If there are concerns that the search result data may be too large and exceed the prompt size, consider reducing the size of the search result data by using AZURE_AI_SEARCH_SEARCH_OPTION_TOP and AZURE_AI_SEARCH_SEARCH_OPTION_SELECT.
For details on each parameter, please refer to the following document:
-https://learn.microsoft.com/en-us/rest/api/searchservice/search-documents
+**[https://learn.microsoft.com/en-us/rest/api/searchservice/search-documents](https://learn.microsoft.com/en-us/rest/api/searchservice/search-documents)**
```env
AZURE_AI_SEARCH_API_VERSION=2023-10-01-Preview
diff --git a/docs/features/plugins/chatgpt_plugins_openapi.md b/docs/features/plugins/chatgpt_plugins_openapi.md
index abf8a625c642..7bf8a04a0e45 100644
--- a/docs/features/plugins/chatgpt_plugins_openapi.md
+++ b/docs/features/plugins/chatgpt_plugins_openapi.md
@@ -1,16 +1,17 @@
---
title: 🧑💼 Official ChatGPT Plugins
+description: How to add official OpenAI Plugins to LibreChat
weight: -8
---
# Using official ChatGPT Plugins / OpenAPI specs
ChatGPT plugins are API integrations for OpenAI models that extend their capabilities. They are structured around three key components: an API, an **OpenAPI specification** (spec for short), and a JSON **Plugin Manifest** file.
-To learn more about them, or how to make your own, read here: [ChatGPT Plugins: Getting Started](https://platform.openai.com/docs/plugins/getting-started).
+To learn more about them, or how to make your own, read here: **[ChatGPT Plugins: Getting Started](https://platform.openai.com/docs/plugins/getting-started)**
-Thanks to the introduction of [OpenAI Functions](https://openai.com/blog/function-calling-and-other-api-updates) and their utilization in [Langchain](https://js.langchain.com/docs/modules/chains/openai_functions/openapi), it's now possible to directly use OpenAI Plugins through LibreChat, without building any custom langchain tools. The main use case we gain from integrating them to LibreChat is to allow use of plugins with gpt-3.5 models, and without ChatGPT Plus. They also find a great use case when you want to limit your own private API's interactions with chat.openai.com and their servers in favor of a self-hosted LibreChat instance.
+Thanks to the introduction of **[OpenAI Functions](https://openai.com/blog/function-calling-and-other-api-updates)** and their utilization in **[Langchain](https://js.langchain.com/docs/modules/chains/openai_functions/openapi)**, it's now possible to directly use OpenAI Plugins through LibreChat, without building any custom langchain tools. The main use case we gain from integrating them to LibreChat is to allow use of plugins with gpt-3.5 models, and without ChatGPT Plus. They also find a great use case when you want to limit your own private API's interactions with chat.openai.com and their servers in favor of a self-hosted LibreChat instance.
-### Table of Contents
+
## Intro
@@ -32,11 +33,11 @@ Before continuing, it's important to fully distinguish what a Manifest file is v
### **[Plugin Manifest File:](https://platform.openai.com/docs/plugins/getting-started/plugin-manifest)**
- Usually hosted on the API’s domain as `https://example.com/.well-known/ai-plugin.json`
- The manifest file is required for LLMs to connect with your plugin. If there is no file found, the plugin cannot be installed.
-- Has required properties, and will error if they are missing. Check what they are in the [OpenAI Docs](https://platform.openai.com/docs/plugins/getting-started/plugin-manifest)
+- Has required properties, and will error if they are missing. Check what they are in the **[OpenAI Docs](https://platform.openai.com/docs/plugins/getting-started/plugin-manifest)**
- Has optional properties, specific to LibreChat, that will enable them to work consistently, or for customizing headers/params made by every API call (see below)
### **[OpenAPI Spec](https://platform.openai.com/docs/plugins/getting-started/openapi-definition)**
-- The OpenAPI specification is used to document the API that the plugin will interact with. It is a [universal format](https://www.openapis.org/) meant to standardize API definitions.
+- The OpenAPI specification is used to document the API that the plugin will interact with. It is a **[universal format](https://www.openapis.org/)** meant to standardize API definitions.
- Referenced by the Manifest file in its `api.url` property
- Usually as `https://example.com/openapi.yaml` or `.../swagger.yaml`
- Can be a .yaml or .json file
@@ -53,7 +54,7 @@ Download the Plugin manifest file, or copy the raw JSON data into a new file, an
`api\app\clients\tools\.well-known`
-You should see multiple manifest files that have been tested, or edited, to work with LibreChat. ~~I've renamed them by their `name_for_model` property and it's recommended, but not required, that you do the same.~~ As of v0.5.8, It's **required** to name the manifest JSON file after its `name_for_model` property should you add one yourself.
+You should see multiple manifest files that have been tested, or edited, to work with LibreChat. As of v0.5.8, It's **required** to name the manifest JSON file after its `name_for_model` property should you add one yourself.
After doing so, start/re-start the project server and they should now load in the Plugin store.
@@ -152,7 +153,7 @@ curl -H "Authorization: Bearer ffc5226d1af346c08a98dee7deec9f76" https://example
As of now, LibreChat only supports plugins using Bearer Authentication, like in the example above.
-If your plugin requires authentication, it's necessary to have these fields filled in your manifest file according to [OpenAI definitions](https://platform.openai.com/docs/plugins/getting-started/plugin-manifest), which for Bearer Authentication must follow the schema above.
+If your plugin requires authentication, it's necessary to have these fields filled in your manifest file according to **[OpenAI definitions](https://platform.openai.com/docs/plugins/getting-started/plugin-manifest)**, which for Bearer Authentication must follow the schema above.
Important: Some ChatGPT plugins may use Bearer Auth., but have either stale verification tokens in their manifest, or only support calls from OpenAI servers. Web Pilot is one with the latter case, and thankfully it has a required header field for allowing non-OpenAI origination. See above for editing headers.
@@ -168,16 +169,16 @@ Important: Some ChatGPT plugins may use Bearer Auth., but have either stale veri
## Disclaimers
-Use of ChatGPT Plugins is only possible with official OpenAI models and their use of [Functions](https://platform.openai.com/docs/api-reference/chat/create#chat/create-functions). If you are accessing OpenAI models via reverse proxy through some 3rd party service, function calling may not be supported.
+Use of ChatGPT Plugins is only possible with official OpenAI models and their use of **[Functions](https://platform.openai.com/docs/api-reference/chat/create#chat/create-functions)**. If you are accessing OpenAI models via reverse proxy through some 3rd party service, function calling may not be supported.
-This implementation depends on the [LangChain OpenAPI Chain](https://js.langchain.com/docs/modules/chains/openai_functions/openapi) and general improvements to its use here will have to be made to the LangChainJS library.
+This implementation depends on the **[LangChain OpenAPI Chain](https://js.langchain.com/docs/modules/chains/openai_functions/openapi)** and general improvements to its use here will have to be made to the LangChainJS library.
Custom Langchain Tools are preferred over ChatGPT Plugins/OpenAPI specs as this can be more token-efficient, especially with OpenAI Functions. A better alternative may be to make a Langchain tool modelled after an OpenAPI spec, for which I'll make a guide soon.
LibreChat's implementation is not 1:1 with ChatGPT's, as OpenAI has a robust, exclusive, and restricted authentication pipeline with its models & specific plugins, which are not as limited by context windows and token usage. Furthermore, some of their hosted plugins requiring authentication will not work, especially those with OAuth or stale verification tokens, and some may not be handled by the LLM in the same manner, especially those requiring multi-step API calls.
-Some plugins may detect that the API call does not originate from OpenAI's servers, will either be defunct outside of chat.openai.com or need special handling, and/or editing of their manifest/spec files. This is not to say plugin use will not improve and more closely mirror how ChatGPT handles plugins, but there is still work to this end. In short, some will work perfectly while others may not work at all.
+Some plugins may detect that the API call does not originate from OpenAI's servers, will either be defunct outside of **[chat.openai.com](https://chat.openai.com/)** or need special handling, and/or editing of their manifest/spec files. This is not to say plugin use will not improve and more closely mirror how ChatGPT handles plugins, but there is still work to this end. In short, some will work perfectly while others may not work at all.
-The use of ChatGPT Plugins with LibreChat does not violate OpenAI's [Terms of Service](https://openai.com/policies/terms-of-use). According to their [Service Terms](https://openai.com/policies/service-terms) and [Usage Policies](https://openai.com/policies/usage-policies), the host, in this case OpenAI, is not responsible for the plugins hosted on their site and their usage outside of their platform, chat.openai.com. Furthermore, there is no explicit mention of restrictions on accessing data that is not directly displayed to the user. Therefore, accessing the payload of their plugins for display purposes is not in violation of their Terms of Service.
+The use of ChatGPT Plugins with LibreChat does not violate OpenAI's **[Terms of Service](https://openai.com/policies/terms-of-use)**. According to their **[Service Terms](https://openai.com/policies/service-terms)** and **[Usage Policies](https://openai.com/policies/usage-policies)**, the host, in this case OpenAI, is not responsible for the plugins hosted on their site and their usage outside of their platform, **[chat.openai.com](https://chat.openai.com/)**. Furthermore, there is no explicit mention of restrictions on accessing data that is not directly displayed to the user. Therefore, accessing the payload of their plugins for display purposes is not in violation of their Terms of Service.
-Please note that the ChatGPT Plugins integration is currently in an alpha state, and you may encounter errors. Although preliminary testing has been conducted, not all plugins have been thoroughly tested, and you may find that some I haven't added will not work for any one of the reasons I've mentioned above. Some of the errors may be caused by the plugin itself, and will also not work on https://chat.openai.com/. If you encounter any errors, double checking if they work on the official site is advisable before reporting them as a GitHub issue. I can only speak for the ones I tested and included, and the date of inclusion.
+Please note that the ChatGPT Plugins integration is currently in an alpha state, and you may encounter errors. Although preliminary testing has been conducted, not all plugins have been thoroughly tested, and you may find that some I haven't added will not work for any one of the reasons I've mentioned above. Some of the errors may be caused by the plugin itself, and will also not work on **[chat.openai.com](https://chat.openai.com/)**. If you encounter any errors, double checking if they work on the official site is advisable before reporting them as a GitHub issue. I can only speak for the ones I tested and included, and the date of inclusion.
diff --git a/docs/features/plugins/google_search.md b/docs/features/plugins/google_search.md
index 0618be8b649e..0b575414f2c6 100644
--- a/docs/features/plugins/google_search.md
+++ b/docs/features/plugins/google_search.md
@@ -1,5 +1,6 @@
---
title: 🔎 Google Search
+description: How to set up and use the Google Search Plugin, which allows you to query Google with GPT's help.
weight: -7
---
@@ -10,9 +11,9 @@ GOOGLE_API_KEY="...."
GOOGLE_CSE_ID="...."
```
-You first need to create a programmable search engine and get the search engine ID: https://developers.google.com/custom-search/docs/tutorial/creatingcse
+You first need to create a programmable search engine and get the search engine ID: **[https://developers.google.com/custom-search/docs/tutorial/creatingcse](https://developers.google.com/custom-search/docs/tutorial/creatingcse)**
-Then you can get the API key, click the "Get a key" button on this page: https://developers.google.com/custom-search/v1/introduction
+Then you can get the API key, click the "Get a key" button on this page: **[https://developers.google.com/custom-search/v1/introduction](https://developers.google.com/custom-search/v1/introduction)**
diff --git a/docs/features/plugins/index.md b/docs/features/plugins/index.md
index 681266e56bad..7eb2d3f15399 100644
--- a/docs/features/plugins/index.md
+++ b/docs/features/plugins/index.md
@@ -1,5 +1,6 @@
---
title: Plugins
+description: 🔌 All about plugins, how to make them, how use the official ChatGPT plugins, and how to configure custom plugins.
weight: -10
---
diff --git a/docs/features/plugins/introduction.md b/docs/features/plugins/introduction.md
index f2320fb4a208..f5533c82bf1d 100644
--- a/docs/features/plugins/introduction.md
+++ b/docs/features/plugins/introduction.md
@@ -1,5 +1,6 @@
---
title: 🔌 Introduction
+description: This doc introduces the plugins endpoint, which enables you to use different LLMs and tools with more flexibility and control. You can change your settings and plugins on the fly, and use plugins to access various sources of information and assistance.
weight: -10
---
# Plugins Endpoint
@@ -9,7 +10,7 @@ weight: -10
The plugins endpoint opens the door to prompting LLMs in new ways other than traditional input/output prompting.
-The first step is using chain-of-thought prompting & ["agency"](https://zapier.com/blog/ai-agent/) for using plugins/tools in a fashion mimicing the official ChatGPT Plugins feature.
+The first step is using chain-of-thought prompting & **["agency"](https://zapier.com/blog/ai-agent/)** for using plugins/tools in a fashion mimicing the official ChatGPT Plugins feature.
More than this, you can use this endpoint for changing your conversation settings mid-conversation. Unlike the official ChatGPT site and all other endpoints, you can switch models, presets, and settings mid-convo, even when you have no plugins selected. This is useful if you first want a creative response from GPT-4, and then a deterministic, lower cost response from GPT-3. Soon, you will be able to use Google, HuggingFace, local models, all in this or a similar endpoint in the same modular manner.
@@ -52,8 +53,8 @@ Clicking on **"Show Agent Settings"** will allow you to modify parameters for th
- **[Stable Diffusion](./stable_diffusion.md)**
- **[Wolfram](./wolfram.md)**
- **DALL-E** - same setup as above, you just need an OpenAI key, and it's made distinct from your main API key to make Chats but it can be the same one
-- **Zapier** - You need a Zapier account. Get your [API key from here](https://nla.zapier.com/credentials/) after you've made an account
- - Create allowed actions - Follow step 3 in this [getting start guide](https://nla.zapier.com/start/) from Zapier
+- **Zapier** - You need a Zapier account. Get your **[API key from here](https://nla.zapier.com/credentials/)** after you've made an account
+ - Create allowed actions - Follow step 3 in this **[Start Here guide](https://nla.zapier.com/start/)** from Zapier
- ⚠️ NOTE: zapier is known to be finicky with certain actions. I found that writing email drafts is probably the best use of it
- there are improvements that can be made to override the official NLA integration and that is TBD
- **Browser/Scraper** - This is not to be confused with 'browsing' on chat.openai.com (which is technically a plugin suite or multiple plugins)
@@ -62,7 +63,7 @@ Clicking on **"Show Agent Settings"** will allow you to modify parameters for th
- A better solution for 'browsing' is planned but can't guarantuee when
- This plugin is best used in combination with google so it doesn't hallucinate webpages to visit
- **Serpapi** - an alternative to Google search but not as performant in my opinion
- - You can get an API key here: https://serpapi.com/dashboard
+ - You can get an API key here: **[https://serpapi.com/dashboard](https://serpapi.com/dashboard)**
- For free tier, you are limited to 100 queries/month
- With google, you are limited to 100/day for free, which is a better deal, and any after may cost you a few pennies
diff --git a/docs/features/plugins/make_your_own.md b/docs/features/plugins/make_your_own.md
index d463c94767ec..e6534e47aff0 100644
--- a/docs/features/plugins/make_your_own.md
+++ b/docs/features/plugins/make_your_own.md
@@ -1,5 +1,6 @@
---
title: 🛠️ Make Your Own
+description: This doc shows you how to create custom plugins for LibreChat by extending the LangChain `Tool` class. You will learn how to use different APIs and functions with your plugins, and how to integrate them with the LangChain framework.
weight: -9
---
# Making your own Plugin
@@ -8,11 +9,11 @@ Creating custom plugins for this project involves extending the `Tool` class fro
**Note:** I will use the word plugin interchangeably with tool, as the latter is specific to LangChain, and we are mainly conforming to the library.
-You are essentially creating DynamicTools in LangChain speak. See the [LangChainJS docs](https://js.langchain.com/docs/modules/agents/tools/dynamic) for more info.
+You are essentially creating DynamicTools in LangChain speak. See the **[LangChainJS docs](https://js.langchain.com/docs/modules/agents/tools/dynamic)** for more info.
This guide will walk you through the process of creating your own custom plugins, using the `StableDiffusionAPI` and `WolframAlphaAPI` tools as examples.
-When using the Functions Agent (the default mode for plugins), tools are converted to [OpenAI functions](https://openai.com/blog/function-calling-and-other-api-updates); in any case, plugins/tools are invoked conditionally based on the LLM generating a specific format that we parse.
+When using the Functions Agent (the default mode for plugins), tools are converted to **[OpenAI functions](https://openai.com/blog/function-calling-and-other-api-updates)**; in any case, plugins/tools are invoked conditionally based on the LLM generating a specific format that we parse.
The most common implementation of a plugin is to make an API call based on the natural language input from the AI, but there is virtually no limit in programmatic use case.
@@ -47,7 +48,7 @@ Remember, the key to creating a custom plugin is to extend the `Tool` class and
**Multi-Input Plugins**
-If you would like to make a plugin that would benefit from multiple inputs from the LLM, instead of a singular input string as we will review, you need to make a LangChain [StructuredTool](https://blog.langchain.dev/structured-tools/) instead. A detailed guide for this is in progress, but for now, you can look at how I've made StructuredTools in this directory: `api\app\clients\tools\structured\`. This guide is foundational to understanding StructuredTools, and it's recommended you continue reading to better understand LangChain tools first. The blog linked above is also helpful once you've read through this guide.
+If you would like to make a plugin that would benefit from multiple inputs from the LLM, instead of a singular input string as we will review, you need to make a LangChain **[StructuredTool](https://blog.langchain.dev/structured-tools/)** instead. A detailed guide for this is in progress, but for now, you can look at how I've made StructuredTools in this directory: `api\app\clients\tools\structured\`. This guide is foundational to understanding StructuredTools, and it's recommended you continue reading to better understand LangChain tools first. The blog linked above is also helpful once you've read through this guide.
---
@@ -131,7 +132,7 @@ class StableDiffusionAPI extends Tool {
The `_call` method is where the main functionality of your plugin is implemented. This method is called when the language model decides to use your plugin. It should take an `input` parameter and return a result.
-> In a basic Tool, the LLM will generate one string value as an input. If your plugin requires multiple inputs from the LLM, read the [StructuredTools](#StructuredTools) section.
+> In a basic Tool, the LLM will generate one string value as an input. If your plugin requires multiple inputs from the LLM, read the **[StructuredTools](#StructuredTools)** section.
```javascript
class StableDiffusionAPI extends Tool {
diff --git a/docs/features/plugins/stable_diffusion.md b/docs/features/plugins/stable_diffusion.md
index fd02c0d3bd63..e9734cc511fe 100644
--- a/docs/features/plugins/stable_diffusion.md
+++ b/docs/features/plugins/stable_diffusion.md
@@ -1,17 +1,18 @@
---
title: 🖌️ Stable Diffusion
+description: How to set up and configure the Stable Diffusion plugin
weight: -6
---
# Stable Diffusion Plugin
-To use Stable Diffusion with this project, you will either need to download and install [stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) or, for a dockerized deployment, you can also use [stable-diffusion-webui-docker](https://github.com/AbdBarho/stable-diffusion-webui-docker)
+To use Stable Diffusion with this project, you will either need to download and install **[AUTOMATIC1111 - Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui)** or, for a dockerized deployment, you can also use **[stable-diffusion-webui-docker](https://github.com/AbdBarho/stable-diffusion-webui-docker)**
With the docker deployment you can skip step 2 and step 3, use the setup instructions from their repository instead.
- Note: you need a compatible GPU ("CPU-only" is possible but very slow). Nvidia is recommended, but there is no clear resource on incompatible GPUs. Any decent GPU should work.
-## 1. Follow download and installation instructions from [stable-diffusion-webui readme](https://github.com/AUTOMATIC1111/stable-diffusion-webui)
+## 1. Follow download and installation instructions from **[stable-diffusion-webui readme](https://github.com/AUTOMATIC1111/stable-diffusion-webui)**
## 2. Edit your run script settings
diff --git a/docs/features/plugins/wolfram.md b/docs/features/plugins/wolfram.md
index c0d74ea0d915..0237e2d515f8 100644
--- a/docs/features/plugins/wolfram.md
+++ b/docs/features/plugins/wolfram.md
@@ -1,5 +1,6 @@
---
title: 🧠 Wolfram|Alpha
+description: How to set up and configure the Wolfram Alpha plugin
weight: -5
---
@@ -9,18 +10,23 @@ An AppID must be supplied in all calls to the Wolfram|Alpha API.
- Note: Wolfram API calls are limited to 100 calls/day and 2000/month for regular users.
-## 1. Make an account at Wolfram|Alpha
-## 2. Go to the Developer Portal click on "Get an AppID".
-## 3. Configure it in LibreChat
-### Select the plugins endpoint
+### Make an account
+- Visit: **[products.wolframalpha.com/api/](https://products.wolframalpha.com/api/)** to create your account
+
+### Get your AppID
+- Go to the **[Developer Portal](https://developer.wolframalpha.com/portal/myapps/)** click on `Get an AppID`.
+
+### Configure it in LibreChat
+- Select the plugins endpoint
![plugins_endpoint](https://github.com/danny-avila/LibreChat/assets/32828263/7db788a5-2173-4115-b34b-43ea132dae69)
-### Open the Plugin store
+- Open the Plugin store
![plugin_store](https://github.com/danny-avila/LibreChat/assets/32828263/12a51feb-c030-4cf0-8429-16360270988d)
-### Install Wolfram and Provide your AppID
+- Install Wolfram and Provide your AppID
![wolfram-1](https://github.com/danny-avila/LibreChat/assets/32828263/bd165497-d529-441d-8372-a68db19adc3f)
-- Alternatively: you (the admin) can set the value in `\.env` to bypass the prompt: `WOLFRAM_APP_ID=your_app_id`
+> Alternatively: you (the admin) can set the value in `\.env` to bypass the prompt: `WOLFRAM_APP_ID=your_app_id`
+
-## 5. Select the plugin and enjoy!
+### Select the plugin and enjoy!
![wolfram-2](https://github.com/danny-avila/LibreChat/assets/32828263/2825e961-6c46-4728-96cd-1012a0862943)
diff --git a/docs/features/presets.md b/docs/features/presets.md
index b545ab17756c..3f26cd8411ff 100644
--- a/docs/features/presets.md
+++ b/docs/features/presets.md
@@ -1,5 +1,6 @@
---
title: 🔖 Presets
+description: The "presets" feature in our app is a powerful tool that allows users to save and load predefined settings for their conversations. Users can import and export these presets as JSON files, set a default preset, and share them with others on Discord.
weight: -9
---
# Guide to Using the "Presets" Feature
diff --git a/docs/features/third_party.md b/docs/features/third_party.md
index 22c63794bc3d..3161e4404020 100644
--- a/docs/features/third_party.md
+++ b/docs/features/third_party.md
@@ -1,5 +1,6 @@
---
title: ✨ Third-Party Tools and Contributions
+description: Collection of third-party tools provided by the community
weight: -2
---
diff --git a/docs/features/token_usage.md b/docs/features/token_usage.md
index da2e86b8a435..876b385f97c5 100644
--- a/docs/features/token_usage.md
+++ b/docs/features/token_usage.md
@@ -1,5 +1,6 @@
---
title: 🪙 Token Usage
+description: This doc covers how to track and control your token usage for the OpenAI/Plugins endpoints in LibreChat. You will learn how to view your transactions, enable user balances, and add credits to your account.
weight: -7
---
# Token Usage
diff --git a/docs/general_info/breaking_changes.md b/docs/general_info/breaking_changes.md
index 09690376319e..9991d42f6ff0 100644
--- a/docs/general_info/breaking_changes.md
+++ b/docs/general_info/breaking_changes.md
@@ -1,5 +1,6 @@
---
title: ⚠️ Breaking Changes
+description: This doc lists the breaking changes that affect the functionality and compatibility of LibreChat. You should read this doc before updating to a new version of LibreChat, and follow the instructions to resolve any issues.
weight: -10
---
# ⚠️ Breaking Changes
diff --git a/docs/general_info/index.md b/docs/general_info/index.md
index 6edb7921d32d..1addb356e703 100644
--- a/docs/general_info/index.md
+++ b/docs/general_info/index.md
@@ -1,5 +1,6 @@
---
title: General Information
+description: 📜 This section contains information about LibreChat, such as its history, purpose, and values. You will also find the details of the tech stack, the code of conduct, and the breaking changes that affect the project.
weight: 4
---
diff --git a/docs/general_info/multilingual_information.md b/docs/general_info/multilingual_information.md
index c1bc38988bae..5b51c4eea572 100644
--- a/docs/general_info/multilingual_information.md
+++ b/docs/general_info/multilingual_information.md
@@ -1,5 +1,6 @@
---
title: 🌍 Multilingual Information
+description: To set up the project, please follow the instructions in the documentation. The documentation is in English only, so you may need to use a translation tool or an AI assistant (e.g. ChatGPT) if you have difficulty understanding it.
weight: -9
---
# Multilingual Information
diff --git a/docs/general_info/project_origin.md b/docs/general_info/project_origin.md
index ea16ebd07934..d1dc673238fe 100644
--- a/docs/general_info/project_origin.md
+++ b/docs/general_info/project_origin.md
@@ -1,5 +1,6 @@
---
title: 🧭 Origin
+description: How it all started...
weight: -8
---
# Origin
diff --git a/docs/general_info/tech_stack.md b/docs/general_info/tech_stack.md
index 3ef2d1112e62..acb0100b5bf8 100644
--- a/docs/general_info/tech_stack.md
+++ b/docs/general_info/tech_stack.md
@@ -1,5 +1,6 @@
---
title: 🧑💻 Tech Stack
+description: This doc describes the technologies and frameworks that LibreChat uses.
weight: -8
---
# Tech Stack
diff --git a/docs/index.md b/docs/index.md
index 36515634247b..3abf481c36d9 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,3 +1,9 @@
+---
+title: Home
+description: 🪶 Introducing LibreChat
+weight: -10
+---
+
+Get an API key here: **[makersuite.google.com](https://makersuite.google.com/app/apikey)**
Once you have your key, provide the key in your .env file, which allows all users of your instance to use it.
@@ -147,13 +147,13 @@ Setting `GOOGLE_KEY=user_provided` in your .env file will configure both the Ver
### Vertex AI (PaLM 2 & Codey)
-To setup Google LLMs (via Google Cloud Vertex AI), first, signup for Google Cloud: https://cloud.google.com/
+To setup Google LLMs (via Google Cloud Vertex AI), first, signup for Google Cloud: **[cloud.google.com](https://cloud.google.com/)**
You can usually get **$300 starting credit**, which makes this option free for 90 days.
### 1. Once signed up, Enable the Vertex AI API on Google Cloud:
- - Go to [Vertex AI page on Google Cloud console](https://console.cloud.google.com/vertex-ai)
- - Click on "Enable API" if prompted
+ - Go to **[Vertex AI page on Google Cloud console](https://console.cloud.google.com/vertex-ai)**
+ - Click on `Enable API` if prompted
### 2. Create a Service Account with Vertex AI role:
- **[Click here to create a Service Account](https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts/create?walkthrough_id=iam--create-service-account#step_index=1)**
- **Select or create a project**
@@ -214,11 +214,11 @@ You should also consider changing the `AZURE_OPENAI_MODELS` variable to the mode
AZURE_OPENAI_MODELS=gpt-4-1106-preview,gpt-4,gpt-3.5-turbo,gpt-3.5-turbo-1106,gpt-4-vision-preview
```
-Overriding the construction of the API URL will be possible but is not yet implemented. Follow progress on this feature here: [Issue #1266](https://github.com/danny-avila/LibreChat/issues/1266)
+Overriding the construction of the API URL will be possible but is not yet implemented. Follow progress on this feature here: **[Issue #1266](https://github.com/danny-avila/LibreChat/issues/1266)**
### Model Deployments
-*Note: a change will be developed to improve current configuration settings, to allow multiple deployments/model configurations setup with ease: [#1390](https://github.com/danny-avila/LibreChat/issues/1390)*
+> Note: a change will be developed to improve current configuration settings, to allow multiple deployments/model configurations setup with ease: **[#1390](https://github.com/danny-avila/LibreChat/issues/1390)**
As of 2023-12-18, the Azure API allows only one model per deployment.
@@ -297,7 +297,7 @@ As of December 18th, 2023, Vision models seem to have degraded performance with
![image](https://github.com/danny-avila/LibreChat/assets/110412045/7306185f-c32c-4483-9167-af514cc1c2dd)
-*Note: a change will be developed to improve current configuration settings, to allow multiple deployments/model configurations setup with ease: [#1390](https://github.com/danny-avila/LibreChat/issues/1390)*
+> Note: a change will be developed to improve current configuration settings, to allow multiple deployments/model configurations setup with ease: **[#1390](https://github.com/danny-avila/LibreChat/issues/1390)**
### Optional Variables
@@ -310,7 +310,7 @@ These two variables are optional but may be used in future updates of this proje
### Using Plugins with Azure
-Note: To use the Plugins endpoint with Azure OpenAI, you need a deployment supporting [function calling](https://techcommunity.microsoft.com/t5/azure-ai-services-blog/function-calling-is-now-available-in-azure-openai-service/ba-p/3879241). Otherwise, you need to set "Functions" off in the Agent settings. When you are not using "functions" mode, it's recommend to have "skip completion" off as well, which is a review step of what the agent generated.
+Note: To use the Plugins endpoint with Azure OpenAI, you need a deployment supporting **[function calling](https://techcommunity.microsoft.com/t5/azure-ai-services-blog/function-calling-is-now-available-in-azure-openai-service/ba-p/3879241)**. Otherwise, you need to set "Functions" off in the Agent settings. When you are not using "functions" mode, it's recommend to have "skip completion" off as well, which is a review step of what the agent generated.
To use Azure with the Plugins endpoint, make sure the following environment variables are set:
@@ -321,19 +321,19 @@ To use Azure with the Plugins endpoint, make sure the following environment vari
## [OpenRouter](https://openrouter.ai/)
-[OpenRouter](https://openrouter.ai/) is a legitimate proxy service to a multitude of LLMs, both closed and open source, including:
+**[OpenRouter](https://openrouter.ai/)** is a legitimate proxy service to a multitude of LLMs, both closed and open source, including:
- OpenAI models (great if you are barred from their API for whatever reason)
- Anthropic Claude models (same as above)
- Meta's Llama models
- pygmalionai/mythalion-13b
- and many more open source models. Newer integrations are usually discounted, too!
-> See their available models and pricing here: [Supported Models](https://openrouter.ai/docs#models)
+> See their available models and pricing here: **[Supported Models](https://openrouter.ai/docs#models)**
OpenRouter is so great, I decided to integrate it to the project as a standalone feature.
**Setup:**
-- Signup to [OpenRouter](https://openrouter.ai/) and create a key. You should name it and set a limit as well.
+- Signup to **[OpenRouter](https://openrouter.ai/)** and create a key. You should name it and set a limit as well.
- Set the environment variable `OPENROUTER_API_KEY` in your .env file to the key you just created.
- Set something in the `OPENAI_API_KEY`, it can be anyting, but **do not** leave it blank or set to `user_provided`
- Restart your LibreChat server and use the OpenAI or Plugins endpoints.
@@ -364,12 +364,12 @@ This is not to be confused with [OpenAI's Official API](#openai)!
To get your Access token for ChatGPT Browser Access, you need to:
-- Go to [https://chat.openai.com](https://chat.openai.com)
+- Go to **[https://chat.openai.com](https://chat.openai.com)**
- Create an account or log in with your existing one
-- Visit [https://chat.openai.com/api/auth/session](https://chat.openai.com/api/auth/session)
+- Visit **[https://chat.openai.com/api/auth/session](https://chat.openai.com/api/auth/session)**
- Copy the value of the "accessToken" field and save it in ./.env as CHATGPT_ACCESS_TOKEN
-Warning: There may be a chance of your account being banned if you deploy the app to multiple users with this method. Use at your own risk. 😱
+Warning: There may be a chance of your account being banned if you deploy the app to multiple users with this method. Use at your own risk.
---
diff --git a/docs/install/configuration/default_language.md b/docs/install/configuration/default_language.md
index faab9047d921..8255489c5710 100644
--- a/docs/install/configuration/default_language.md
+++ b/docs/install/configuration/default_language.md
@@ -1,5 +1,6 @@
---
title: 🌍 Default Language
+description: How to change LibreChat's default language
weight: -3
---
diff --git a/docs/install/configuration/docker_override.md b/docs/install/configuration/docker_override.md
index 9b1284513e78..a1a54b4e3097 100644
--- a/docs/install/configuration/docker_override.md
+++ b/docs/install/configuration/docker_override.md
@@ -1,5 +1,6 @@
---
title: 🐋 Docker Compose Override
+description: "How to Use the Docker Compose Override File: In Docker Compose, an override file is a powerful feature that allows you to modify the default configuration provided by the main `docker-compose.yml` without the need to directly edit or duplicate the whole file."
weight: -9
---
diff --git a/docs/install/configuration/dotenv.md b/docs/install/configuration/dotenv.md
index 55ab65aad5c9..ea3cd097d945 100644
--- a/docs/install/configuration/dotenv.md
+++ b/docs/install/configuration/dotenv.md
@@ -1,5 +1,6 @@
---
title: ⚙️ Environment Variables
+description: Comprehensive guide for configuring your application's environment with the `.env` file. This document is your one-stop resource for understanding and customizing the environment variables that will shape your application's behavior in different contexts.
weight: -10
---
@@ -98,10 +99,10 @@ NO_INDEX=true
LibreChat has built-in central logging, see [Logging System](../../features/logging_system.md) for more info.
- Debug logging is enabled by default and crucial for development.
-- To report issues, reproduce the error and submit logs from `./api/logs/debug-%DATE%.log` at [LibreChat GitHub Issues](https://github.com/danny-avila/LibreChat/issues).
+- To report issues, reproduce the error and submit logs from `./api/logs/debug-%DATE%.log` at: **[LibreChat GitHub Issues](https://github.com/danny-avila/LibreChat/issues)**
- Error logs are stored in the same location.
- Keep debug logs active by default or disable them by setting `DEBUG_LOGGING=false` in the environment variable.
-- For more information about this feature, read our docs: https://docs.librechat.ai/features/logging_system.html
+- For more information about this feature, read our docs: **[Logging System](../../features/logging_system.md)**
```bash
DEBUG_LOGGING=true
@@ -197,13 +198,13 @@ PLUGINS_USE_AZURE="true"
### BingAI
Bing, also used for Sydney, jailbreak, and Bing Image Creator, see: [Bing Access token](./ai_setup.md#bingai) and [Bing Jailbreak](../../features/bing_jailbreak.md)
-- Follow these instructions to get your bing access token (it's best to use the full cookie string for that purpose): [Bing Access Token](https://github.com/danny-avila/LibreChat/issues/370#issuecomment-1560382302)
+- Follow these instructions to get your bing access token (it's best to use the full cookie string for that purpose): **[Bing Access Token](../configuration/ai_setup.md#bingai)**
- Leave `BINGAI_TOKEN=` blank to disable this endpoint
- Set `BINGAI_TOKEN=` to "user_provided" to allow users to provide their own API key from the WebUI
> Note: It is recommended to leave it as "user_provided" and provide the token from the WebUI.
-- `BINGAI_HOST` can be necessary for some people in different countries, e.g. China (https://cn.bing.com). Leave it blank or commented out to use default server.
+- `BINGAI_HOST` can be necessary for some people in different countries, e.g. China (`https://cn.bing.com`). Leave it blank or commented out to use default server.
```bash
BINGAI_TOKEN=user_provided
@@ -211,7 +212,7 @@ BINGAI_HOST=
```
### ChatGPT
-see: [ChatGPT Free Access token](./ai_setup.md#chatgptbrowser)
+see: [ChatGPT Free Access token](../configuration/ai_setup.md#chatgptbrowser)
> **Warning**: To use this endpoint you'll have to set up your own reverse proxy. Here is the installation guide to deploy your own (based on [PandoraNext](https://github.com/pandora-next/deploy)): **[PandoraNext Deployment Guide](../../features/pandoranext.md)**
@@ -219,8 +220,9 @@ see: [ChatGPT Free Access token](./ai_setup.md#chatgptbrowser)
CHATGPT_REVERSE_PROXY=
```
-> ~~Note: If you're a GPT plus user you can add gpt-4, gpt-4-plugins, gpt-4-code-interpreter, and gpt-4-browsing to the list above and use the models for these features; however, the view/display portion of these features are not supported, but you can use the underlying models, which have higher token context~~
-> **Note:** The current method only works with `text-davinci-002-render-sha`
+> **Note:** If you're a GPT plus user you can try adding `gpt-4`, `gpt-4-plugins`, `gpt-4-code-interpreter`, and `gpt-4-browsing` to the list above and use the models for these features; **however, the view/display portion of these features are not supported**, but you can use the underlying models, which have higher token context
+
+> This method **might only works** with `text-davinci-002-render-sha` and **might stop working** at any moment.
- Leave `CHATGPT_TOKEN=` blank to disable this endpoint
- Set `CHATGPT_TOKEN=` to "user_provided" to allow users to provide their own API key from the WebUI
@@ -348,7 +350,7 @@ DEBUG_PLUGINS=true
```
- For securely storing credentials, you need a fixed key and IV. You can set them here for prod and dev environments.
- - You need a 32-byte key (64 characters in hex) and 16-byte IV (32 characters in hex) You can use this replit to generate some quickly: [Key Generator](https://replit.com/@daavila/crypto#index.js)
+ - You need a 32-byte key (64 characters in hex) and 16-byte IV (32 characters in hex) You can use this replit to generate some quickly: **[Key Generator](https://replit.com/@daavila/crypto#index.js)**
> Warning: If you don't set them, the app will crash on startup.
@@ -379,7 +381,7 @@ AZURE_AI_SEARCH_SEARCH_OPTION_SELECT=
```
- For customization of the DALL-E-3 System prompt, uncomment the following, and provide your own prompt. **(Advanced)**
- - See official prompt for reference: [DALL-E System Prompt](https://github.com/spdustin/ChatGPT-AutoExpert/blob/main/_system-prompts/dall-e.md)
+ - See official prompt for reference: **[DALL-E System Prompt](https://github.com/spdustin/ChatGPT-AutoExpert/blob/main/_system-prompts/dall-e.md)**
```bash
DALLE3_SYSTEM_PROMPT="Your System Prompt here"
@@ -418,23 +420,23 @@ SERPAPI_API_KEY=
```
#### Stable Diffusion (Automatic1111)
-See detailed instructions here: [Stable Diffusion](../../features/plugins/stable_diffusion.md)
+See detailed instructions here: **[Stable Diffusion](../../features/plugins/stable_diffusion.md)**
-- Use "http://127.0.0.1:7860" with local install and "http://host.docker.internal:7860" for docker
+- Use `http://127.0.0.1:7860` with local install and `http://host.docker.internal:7860` for docker
```bash
SD_WEBUI_URL=http://host.docker.internal:7860
```
#### WolframAlpha
-See detailed instructions here: [Wolfram Alpha](../../features/plugins/wolfram.md)
+See detailed instructions here: **[Wolfram Alpha](../../features/plugins/wolfram.md)**
```bash
WOLFRAM_APP_ID=
```
#### Zapier
-- You need a Zapier account. Get your API key from here: [Zapier](https://nla.zapier.com/credentials/)
+- You need a Zapier account. Get your API key from here: **[Zapier](https://nla.zapier.com/credentials/)**
- Create allowed actions - Follow step 3 in this getting start guide from Zapier
> Note: zapier is known to be finicky with certain actions. Writing email drafts is probably the best use of it.
@@ -488,7 +490,7 @@ This section contains the configuration for:
### Moderation
The Automated Moderation System uses a scoring mechanism to track user violations. As users commit actions like excessive logins, registrations, or messaging, they accumulate violation scores. Upon reaching a set threshold, the user and their IP are temporarily banned. This system ensures platform security by monitoring and penalizing rapid or suspicious activities.
-see: [Automated Moderation](../../features/mod_system.md)
+see: **[Automated Moderation](../../features/mod_system.md)**
#### Basic Moderation Settings
@@ -575,7 +577,7 @@ MESSAGE_USER_WINDOW=1
### Balance
The following enables user balances for the OpenAI/Plugins endpoints, which you can add manually or you will need to build out a balance accruing system for users.
-see: [Token Usage](../../features/token_usage.md)
+see: **[Token Usage](../../features/token_usage.md)**
- To manually add balances, run the following command:`npm run add-balance`
- You can also specify the email and token credit amount to add, e.g.:`npm run add-balance example@example.com 1000`
@@ -589,7 +591,7 @@ CHECK_BALANCE=false
```
### Registration and Login
-see: [User/Auth System](../configuration/user_auth_system.md)
+see: **[User/Auth System](../configuration/user_auth_system.md)**
![image](https://github.com/danny-avila/LibreChat/assets/81851188/52a37d1d-7392-4a9a-a79f-90ed2da7f841)
@@ -609,7 +611,7 @@ ALLOW_SOCIAL_REGISTRATION=false
```
- Default values: session expiry: 15 minutes, refresh token expiry: 7 days
- - For more information: [Refresh Token](https://github.com/danny-avila/LibreChat/pull/927)
+ - For more information: **[Refresh Token](https://github.com/danny-avila/LibreChat/pull/927)**
```bash
SESSION_EXPIRY=1000 * 60 * 15
@@ -617,7 +619,7 @@ REFRESH_TOKEN_EXPIRY=(1000 * 60 * 60 * 24) * 7
```
- You should use new secure values. The examples given are 32-byte keys (64 characters in hex).
- - Use this replit to generate some quickly: [JWT Keys](https://replit.com/@daavila/crypto#index.js)
+ - Use this replit to generate some quickly: **[JWT Keys](https://replit.com/@daavila/crypto#index.js)**
```bash
JWT_SECRET=16f8c0ef4a5d391b26034086c628469d3f9f497f08163ab9b40137092f2909ef
@@ -626,9 +628,9 @@ JWT_REFRESH_SECRET=eaa5191f2914e30b9387fd84e254e4ba6fc51b4654968a9b0803b456a54b8
### Social Logins
-#### [Discord](../configuration/user_auth_system.md#discord-authentication)
+#### [Discord Authentication](../configuration/user_auth_system.md#discord)
-for more information: [Discord](../configuration/user_auth_system.md#discord-authentication)
+for more information: **[Discord](../configuration/user_auth_system.md#discord)**
```bash
# Discord
@@ -637,9 +639,9 @@ DISCORD_CLIENT_SECRET=your_client_secret
DISCORD_CALLBACK_URL=/oauth/discord/callback
```
-#### [Facebook](../configuration/user_auth_system.md#facebook-authentication)
+#### [Facebook Authentication](../configuration/user_auth_system.md#facebook)
-for more information: [Facebook](../configuration/user_auth_system.md#facebook-authentication)
+for more information: **[Facebook Authentication](../configuration/user_auth_system.md#facebook)**
```bash
# Facebook
@@ -648,9 +650,9 @@ FACEBOOK_CLIENT_SECRET=
FACEBOOK_CALLBACK_URL=/oauth/facebook/callback
```
-#### [GitHub](../configuration/user_auth_system.md#github-authentication)
+#### [GitHub Authentication](../configuration/user_auth_system.md#github)
-for more information: [GitHub](../configuration/user_auth_system.md#github-authentication)
+for more information: **[GitHub Authentication](../configuration/user_auth_system.md#github)**
```bash
# GitHub
@@ -659,9 +661,9 @@ GITHUB_CLIENT_SECRET=your_client_secret
GITHUB_CALLBACK_URL=/oauth/github/callback
```
-#### [Google](../configuration/user_auth_system.md#google-authentication)
+#### [Google Authentication](../configuration/user_auth_system.md#google)
-for more information: [Google](../configuration/user_auth_system.md#google-authentication)
+for more information: **[Google Authentication](../configuration/user_auth_system.md#google)**
```bash
# Google
@@ -670,9 +672,9 @@ GOOGLE_CLIENT_SECRET=
GOOGLE_CALLBACK_URL=/oauth/google/callback
```
-#### [OpenID](../configuration/user_auth_system.md#openid-authentication-with-azure-ad)
+#### [OpenID Authentication](../configuration/user_auth_system.md#openid-with-aws-cognito)
-for more information: [Azure OpenID](../configuration/user_auth_system.md#openid-authentication-with-azure-ad) or [AWS Cognito OpenID](../configuration/user_auth_system.md#openid-authentication-with-aws-cognito)
+for more information: **[Azure OpenID Authentication](../configuration/user_auth_system.md#openid-with-azure-ad)** or **[AWS Cognito OpenID Authentication](../configuration/user_auth_system.md#openid-with-aws-cognito)**
```bash
# OpenID
@@ -688,7 +690,7 @@ OPENID_IMAGE_URL=
```
### Email Password Reset
-Email is used for password reset. See: [Email Password Reset](../configuration/user_auth_system.md#email-and-password-reset)
+Email is used for password reset. See: **[Email Password Reset](../configuration/user_auth_system.md#email-and-password-reset)**
- Note that all either service or host, username and password and the From address must be set for email to work.
@@ -698,7 +700,7 @@ Email is used for password reset. See: [Email Password Reset](../configuration/u
>
> Failing to set valid values here will result in LibreChat using the unsecured password reset!
-See: [nodemailer well-known-services](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/)
+See: **[nodemailer well-known-services](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/)**
```bash
EMAIL_SERVICE=
diff --git a/docs/install/configuration/free_ai_apis.md b/docs/install/configuration/free_ai_apis.md
index 8478d54a9aa2..671ed9b6206b 100644
--- a/docs/install/configuration/free_ai_apis.md
+++ b/docs/install/configuration/free_ai_apis.md
@@ -1,5 +1,6 @@
---
title: 💸 Free AI APIs
+description: There are APIs offering free/free-trial access to AI APIs via reverse proxy...
weight: -6
---
@@ -7,13 +8,13 @@ weight: -6
There are APIs offering free/free-trial access to AI APIs via reverse proxy.
-Here is a well-maintained public list of [Free AI APIs](https://github.com/zukixa/cool-ai-stuff) that may or may not be compatible with LibreChat
+Here is a well-maintained public list of **[Free AI APIs](https://github.com/zukixa/cool-ai-stuff)** that may or may not be compatible with LibreChat
-> ⚠️ [OpenRouter](./ai_setup.md#openrouter) is in a category of its own, and is highly recommended over the "free" services below. NagaAI and other 'free' API proxies tend to have intermittent issues, data leaks, and/or problems with the guidelines of the platforms they advertise on. Use the below at your own risk.
+> ⚠️ **[OpenRouter](./ai_setup.md#openrouter)** is in a category of its own, and is highly recommended over the "free" services below. NagaAI and other 'free' API proxies tend to have intermittent issues, data leaks, and/or problems with the guidelines of the platforms they advertise on. Use the below at your own risk.
### NagaAI
-Since NagaAI works with LibreChat, and offers Llama2 along with OpenAI models, let's start with that one: [NagaAI](https://t.me/chimera_ai)
+Since NagaAI works with LibreChat, and offers Llama2 along with OpenAI models, let's start with that one: **[NagaAI](https://t.me/chimera_ai)**
> ⚠️ Never trust 3rd parties. Use at your own risk of privacy loss. Your data may be used for AI training at best or for nefarious reasons at worst; this is true in all cases, even with official endpoints: never give an LLM sensitive/identifying information. If something is free, you are the product. If errors arise, they are more likely to be due to the 3rd party, and not this project, as I test the official endpoints first and foremost.
diff --git a/docs/install/configuration/index.md b/docs/install/configuration/index.md
index d89abcc757e9..e577a8b3a564 100644
--- a/docs/install/configuration/index.md
+++ b/docs/install/configuration/index.md
@@ -1,5 +1,6 @@
---
title: Configuration
+description: ⚙️ This section provides detailed guides on how to configure LibreChat to suit your needs and preferences. You will learn how to set up various environment variables, customize your Docker settings, choose your AI models and APIs, enable user authentication, connect to online MongoDB, change the default language, and more.
weight: 2
---
diff --git a/docs/install/configuration/litellm.md b/docs/install/configuration/litellm.md
index b6bb068ead26..c9f86368993a 100644
--- a/docs/install/configuration/litellm.md
+++ b/docs/install/configuration/litellm.md
@@ -1,16 +1,15 @@
---
title: 🚅 LiteLLM
+description: Using LibreChat with LiteLLM Proxy
weight: -7
---
# Using LibreChat with LiteLLM Proxy
-Use [LiteLLM Proxy](https://docs.litellm.ai/docs/simple_proxy) for:
+Use **[LiteLLM Proxy](https://docs.litellm.ai/docs/simple_proxy)** for:
* Calling 100+ LLMs Huggingface/Bedrock/TogetherAI/etc. in the OpenAI ChatCompletions & Completions format
* Load balancing - between Multiple Models + Deployments of the same model LiteLLM proxy can handle 1k+ requests/second during load tests
* Authentication & Spend Tracking Virtual Keys
-https://docs.litellm.ai/docs/simple_proxy
-
## Start LiteLLM Proxy Server
### Pip install litellm
```shell
@@ -18,7 +17,7 @@ pip install litellm
```
### Create a config.yaml for litellm proxy
-More information on LiteLLM configurations here: https://docs.litellm.ai/docs/simple_proxy#proxy-configs
+More information on LiteLLM configurations here: **[docs.litellm.ai/docs/simple_proxy](https://docs.litellm.ai/docs/simple_proxy)**
```yaml
model_list:
diff --git a/docs/install/configuration/misc.md b/docs/install/configuration/misc.md
index 57932d93160f..75892fc7c747 100644
--- a/docs/install/configuration/misc.md
+++ b/docs/install/configuration/misc.md
@@ -1,5 +1,6 @@
---
title: 🌀 Miscellaneous
+description: As LibreChat has varying use cases and environment possibilities, this page will host niche setup/configurations, as contributed by the community, that are not better delegated to any of the other guides.
weight: -2
author: danny-avila and jerkstorecaller
---
@@ -8,8 +9,6 @@ As LibreChat has varying use cases and environment possibilities, this page will
# Using LibreChat behind a reverse proxy with Basic Authentication
-Written by [@danny-avila](https://github.com/danny-avila) and [@jerkstorecaller](https://github.com/jerkstorecaller)
-
### Basic Authentication (Basic Auth)
Basic Authentication is a simple authentication scheme built into the HTTP protocol. When a client sends a request to a server, the server can respond with a `401 Unauthorized` status code, prompting the client to provide a username and password. This username and password are then sent with subsequent requests in the HTTP header, encoded in Base64 format.
diff --git a/docs/install/configuration/mongodb.md b/docs/install/configuration/mongodb.md
index 7ca787aa0537..f280c4d25f87 100644
--- a/docs/install/configuration/mongodb.md
+++ b/docs/install/configuration/mongodb.md
@@ -1,12 +1,13 @@
---
title: 🍃 Online MongoDB
+description: This guide teaches you how to set up an online MongoDB database for LibreChat using MongoDB Atlas, a cloud-based service. You will learn how to create an account, a project, and a cluster, as well as how to configure your database credentials, network access, and connection string.
weight: -4
---
# Set Up an Online MongoDB Database
## Create an account
-- Open a new tab and go to [https://account.mongodb.com/account/register](https://account.mongodb.com/account/register) to create an account.
+- Open a new tab and go to **[account.mongodb.com/account/register](https://account.mongodb.com/account/register)** to create an account.
## Create a project
- Once you have set up your account, create a new project and name it (the name can be anything):
diff --git a/docs/install/configuration/user_auth_system.md b/docs/install/configuration/user_auth_system.md
index 1dae7dfea3db..7020d37ad7b0 100644
--- a/docs/install/configuration/user_auth_system.md
+++ b/docs/install/configuration/user_auth_system.md
@@ -1,5 +1,6 @@
---
title: 🛂 Authentication System
+description: This guide explains how to use the user authentication system of LibreChat, which offers secure and easy email and social logins. You will learn how to set up sign up, log in, password reset, and more.
weight: -5
---
@@ -42,7 +43,7 @@ ALLOW_SOCIAL_REGISTRATION=false
### Session Expiry and Refresh Token
- Default values: session expiry: 15 minutes, refresh token expiry: 7 days
- - For more information: [Refresh Token](https://github.com/danny-avila/LibreChat/pull/927)
+ - For more information: **[GitHub PR #927 - Refresh Token](https://github.com/danny-avila/LibreChat/pull/927)**
```bash
SESSION_EXPIRY=1000 * 60 * 15
@@ -76,7 +77,7 @@ sequenceDiagram
### JWT Secret and Refresh Secret
- You should use new secure values. The examples given are 32-byte keys (64 characters in hex).
- - Use this replit to generate some quickly: [JWT Keys](https://replit.com/@daavila/crypto#index.js)
+ - Use this replit to generate some quickly: **[JWT Keys](https://replit.com/@daavila/crypto#index.js)**
```bash
JWT_SECRET=16f8c0ef4a5d391b26034086c628469d3f9f497f08163ab9b40137092f2909ef
@@ -129,12 +130,12 @@ EMAIL\_ENCRYPTION defines if encryption is required at the start (`tls`) or star
EMAIL\_ENCRYPTION\_HOSTNAME allows specification of a hostname against which the certificate is validated. Use this if the mail server does have a valid certificate, but you are connecting with an IP or a different name for some reason.
EMAIL\_ALLOW\_SELFSIGNED defines whether self-signed certificates can be accepted from the server. As the mails being sent contain sensitive information, ONLY use this for testing.
-NOTE: ⚠️ **Failing to perform either of the below setups will result in LibreChat using the unsecured password reset! This allows anyone to reset any password on your server immediately, without mail being sent at all!** The variable EMAIL\_FROM does not support all email providers **but is still required**. To stay updated, check the bug fixes [here](https://github.com/danny-avila/LibreChat/tags).
+NOTE: ⚠️ **Failing to perform either of the below setups will result in LibreChat using the unsecured password reset! This allows anyone to reset any password on your server immediately, without mail being sent at all!** The variable EMAIL\_FROM does not support all email providers **but is still required**. To stay updated, check the bug fixes: **[here](https://github.com/danny-avila/LibreChat/tags)**
### Setup with Gmail
1. Create a Google Account and enable 2-step verification.
-2. In the [Google Account settings](https://myaccount.google.com/), click on the "Security" tab and open "2-step verification."
+2. In the **[Google Account settings](https://myaccount.google.com/)**, click on the "Security" tab and open "2-step verification."
3. Scroll down and open "App passwords." Choose "Mail" for the app and select "Other" for the device, then give it a random name.
4. Click on "Generate" to create a password, and copy the generated password.
5. In the .env file, modify the variables as follows:
diff --git a/docs/install/index.md b/docs/install/index.md
index 73fe630a66a0..e6177b07b400 100644
--- a/docs/install/index.md
+++ b/docs/install/index.md
@@ -1,5 +1,6 @@
---
title: Installation and Configuration
+description: 💻 In-depth guides about installation and configuration
weight: 1
---
@@ -8,7 +9,7 @@ weight: 1
## **[Installation](./installation/index.md)**
* 🐳 [Docker Compose (✨ Recommended)](./installation/docker_compose_install.md)
- * 🦦 [Container (podman)](./installation/container_install.md)
+ * 🦦 [Container (Podman)](./installation/container_install.md)
* 🐧 [Linux](./installation/linux_install.md)
* 🍎 [Mac](./installation/mac_install.md)
* 🪟 [Windows](./installation/windows_install.md)
diff --git a/docs/install/installation/container_install.md b/docs/install/installation/container_install.md
index 0e43da3dc84c..5f47f1e44cd3 100644
--- a/docs/install/installation/container_install.md
+++ b/docs/install/installation/container_install.md
@@ -1,9 +1,10 @@
---
-title: 🦦 Container (podman)
+title: 🦦 Container (Podman)
+description: Install LibreChat using Podman. If you don't like docker compose, don't want a bare-metal installation, but still want to leverage the benefits from the isolation and modularity of containers...
weight: 0
---
-# Container Installation Guide (podman)
+# Container Installation Guide (Podman)
If you don't like docker compose, don't want a bare-metal installation, but still want to leverage the benefits from the isolation and modularity of containers - this is the guide you should use.
@@ -181,7 +182,7 @@ podman volume export librechat-meilisearch-data --output "librechat-meilisearch-
podman volume export librechat-mongodb-data --output "librechat-mongodb-backup-$(date +"%d-%m-%Y").tar"
```
-These will leave archive files that you can do what you wish with, including reverting volumes to a previous state if needed. Refer to [podman documentation](https://docs.podman.io/en/latest/markdown/podman-volume-import.1.html) for how to do this.
+These will leave archive files that you can do what you wish with, including reverting volumes to a previous state if needed. Refer to the **[official podman documentation](https://docs.podman.io/en/latest/markdown/podman-volume-import.1.html)** for how to do this.
## Updating LibreChat
diff --git a/docs/install/installation/docker_compose_install.md b/docs/install/installation/docker_compose_install.md
index 39786bcc847b..c0f9864839da 100644
--- a/docs/install/installation/docker_compose_install.md
+++ b/docs/install/installation/docker_compose_install.md
@@ -1,5 +1,6 @@
---
title: 🐳 Docker Compose ✨(Recommended)
+description: "Docker Compose Installation Guide: Docker Compose installation is recommended for most use cases. It's the easiest, simplest, and most reliable method to get started."
weight: -10
---
@@ -19,7 +20,7 @@ Start by cloning the repository or downloading it to your desired location:
```
### Docker Installation
-Install Docker on your system. [Docker Desktop](https://www.docker.com/products/docker-desktop/) is recommended for managing your Docker containers.
+Install Docker on your system. **[Docker Desktop](https://www.docker.com/products/docker-desktop/)** is recommended for managing your Docker containers.
### LibreChat Configuration
Before running LibreChat with Docker, you need to configure some settings:
@@ -27,7 +28,7 @@ Before running LibreChat with Docker, you need to configure some settings:
- Edit the credentials you see in `docker-compose.yml` under the API service as needed.
- See my notes below for specific instructions on some of the configuration
- Provide all necessary credentials in the `.env` file before the next step.
- - Docker will read this env file. See the `.env.example` file for reference.
+ - Docker will read this env file. See the **[/.env.example](https://github.com/danny-avila/LibreChat/blob/main/.env.example)** file for reference.
#### [AI Setup](../configuration/ai_setup.md) (Required)
At least one AI endpoint should be setup for use.
diff --git a/docs/install/installation/index.md b/docs/install/installation/index.md
index bd0cb5436625..1b20ac676b29 100644
--- a/docs/install/installation/index.md
+++ b/docs/install/installation/index.md
@@ -1,11 +1,12 @@
---
title: Installation
+description: 🧑💻 This section contains the installation guides for Docker, Podman, Windows, Mac and Linux.
weight: 1
---
# Installation
* 🐳 [Docker Compose (✨ Recommended)](docker_compose_install.md)
- * 🦦 [Container (podman)](container_install.md)
+ * 🦦 [Container (Podman)](container_install.md)
* 🐧 [Linux](linux_install.md)
* 🍎 [Mac](mac_install.md)
* 🪟 [Windows](windows_install.md)
\ No newline at end of file
diff --git a/docs/install/installation/linux_install.md b/docs/install/installation/linux_install.md
index 90f6dc868cf3..d46db47a97d8 100644
--- a/docs/install/installation/linux_install.md
+++ b/docs/install/installation/linux_install.md
@@ -1,5 +1,6 @@
---
title: 🐧 Linux
+description: Linux Installation Guides
weight: 0
---
# Linux Installation Guide
@@ -73,17 +74,17 @@ Note: The above command extracts the files to "/usr/local/LibreChat". If you wan
## Enable the Conversation search feature: (optional)
-- Download MeiliSearch latest release from: https://github.com/meilisearch/meilisearch/releases
-- Copy it to "/usr/local/LibreChat/"
-- Rename the file to "meilisearch"
-- Open a terminal and navigate to "/usr/local/LibreChat/"
+- Download MeiliSearch latest release from: **[github.com/meilisearch](https://github.com/meilisearch/meilisearch/releases)**
+- Copy it to `/usr/local/LibreChat/`
+- Rename the file to `meilisearch`
+- Open a terminal and navigate to `/usr/local/LibreChat/`
- Run the following command:
```bash
./meilisearch --master-key=YOUR_MASTER_KEY
```
-Note: Replace "YOUR_MASTER_KEY" with the generated master key, which you saved earlier.
+Note: Replace `YOUR_MASTER_KEY` with the generated master key, which you saved earlier.
## Install Node.js:
diff --git a/docs/install/installation/mac_install.md b/docs/install/installation/mac_install.md
index 51a1e3d12d3f..f9190bc9c89a 100644
--- a/docs/install/installation/mac_install.md
+++ b/docs/install/installation/mac_install.md
@@ -1,5 +1,6 @@
---
title: 🍎 Mac
+description: Mac Installation Guides
weight: 0
---
@@ -12,7 +13,7 @@ weight: 0
## **Manual Installation**
### Install the prerequisites (Required)
-- Install Homebrew (if not already installed) by following the instructions on https://brew.sh/
+- Install Homebrew (if not already installed) by following the instructions on **[brew.sh](https://brew.sh/)**
- Install Node.js and npm by running `brew install node`
### Download LibreChat (Required)
@@ -38,7 +39,7 @@ weight: 0
### **Download MeiliSearch for macOS (Optional):**
- This enables the conversation search feature
-- You can download the latest MeiliSearch binary for macOS from their GitHub releases page: https://github.com/meilisearch/MeiliSearch/releases
+- You can download the latest MeiliSearch binary for macOS from their GitHub releases page: **[github.com/meilisearch](https://github.com/meilisearch/meilisearch/releases)**
- Look for the file named `meilisearch-macos-amd64` (or the equivalent for your system architecture) and download it.
- **Make the binary executable:**
diff --git a/docs/install/installation/windows_install.md b/docs/install/installation/windows_install.md
index b4a0c24504bc..728dde1e2135 100644
--- a/docs/install/installation/windows_install.md
+++ b/docs/install/installation/windows_install.md
@@ -1,5 +1,6 @@
---
title: 🪟 Windows
+description: Windows Installation Guides
weight: 0
---
@@ -26,8 +27,8 @@ In this video we're going to install LibreChat on Windows 11 using Docker and Gi
#### Instructions
- To install LibreChat, you need Docker desktop and Git. Download them from these links:
- - Docker desktop: https://www.docker.com/products/docke...
- - Git: https://git-scm.com/download/win
+ - Docker desktop: **[https://docs.docker.com/desktop/install/windows-install/](https://docs.docker.com/desktop/install/windows-install/)**
+ - Git: **[https://git-scm.com/download/win](https://git-scm.com/download/win)**
- Follow the steps in the video to install and run Docker desktop and Git.
- Open a terminal in the root of the C drive and enter these commands:
- `git clone https://github.com/danny-avila/LibreChat`
@@ -52,7 +53,7 @@ Have fun!
### Download and Install Node.js (Required)
- - Navigate to https://nodejs.org/en/download and to download the latest Node.js version for your OS (The Node.js installer includes the NPM package manager.)
+ - Navigate to **[https://nodejs.org/en/download](https://nodejs.org/en/download)** and to download the latest Node.js version for your OS (The Node.js installer includes the NPM package manager.)
### Download and Install Git (Recommended)
- Git: https://git-scm.com/download/win
@@ -63,15 +64,12 @@ Have fun!
- At least one AI endpoint should be setup for use.
### Download LibreChat (Required)
- - (With Git) Open Terminal (command prompt) and clone the repository by running `git clone https://github.com/danny-avila/LibreChat.git`
- - Or download the latest release here: https://github.com/danny-avila/LibreChat/releases/
- - Or by clicking on the green code button in the top of the page and selecting "Download ZIP"
- - If you downloaded a zip file, extract the content in "C:/LibreChat/"
+ - Open Terminal (command prompt) and clone the repository by running `git clone https://github.com/danny-avila/LibreChat.git`
- **IMPORTANT : If you install the files somewhere else modify the instructions accordingly**
### Enable the Conversation search feature: (optional)
- - Download MeiliSearch latest release from : https://github.com/meilisearch/meilisearch/releases
+ - Download MeiliSearch latest release from : **[github.com/meilisearch](https://github.com/meilisearch/meilisearch/releases)**
- Copy it to "C:/LibreChat/"
- Rename the file to "meilisearch.exe"
- Open it by double clicking on it
@@ -89,7 +87,7 @@ Using the command line (in the root directory)
### To use the app:
1. Run `npm run backend`
2. Run `meilisearch --master-key ` (Only if SEARCH=TRUE)
-3. Visit http://localhost:3080 (default port) & enjoy
+3. Visit `http://localhost:3080` (default port) & enjoy
### Using a batch file
@@ -98,7 +96,7 @@ Using the command line (in the root directory)
- Paste the following code in a new document
- The meilisearch executable needs to be at the root of the LibreChat directory
- Put your MeiliSearch master key instead of "``"
- - Save the file as "C:/LibreChat/LibreChat.bat"
+ - Save the file as `C:/LibreChat/LibreChat.bat`
- you can make a shortcut of this batch file and put it anywhere
```bat title="LibreChat.bat"
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
deleted file mode 100644
index 9a4d540d58e9..000000000000
--- a/docs/stylesheets/extra.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/*example youtube color scheme*/
-[data-md-color-scheme="youtube"] {
- --md-primary-fg-color: #eee;
- --md-primary-bg-color: #555;
- --md-accent-fg-color: #f00;
- }
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 9dcfa095d57d..ac5d413a3cf4 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -48,15 +48,10 @@ theme:
- navigation.instant.progress
- navigation.tracking
- navigation.expand
- - navigation.prune
+ #- navigation.prune
- navigation.indexes
- navigation.top
-
-# For more Styling options (not in use)
-extra_css:
- - stylesheets/extra.css
-
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
@@ -77,16 +72,32 @@ markdown_extensions:
- name: mermaid
class: mermaid
-
plugins:
- search
+ # - pub-debugger # <- General purpose mkdocs debugger
- mkdocs-nav-weight:
section_renamed: true # If true, section name will use the title of its index instead of the folder name.
index_weight: -10
warning: true # Controls whether to send a Warning when invalid values are detected in markdown metadata
reverse: false # If true, sort nav by weight from largest to smallest.
headless_included: false
-# for more info: https://github.com/shu307/mkdocs-nav-weight?tab=readme-ov-file
+ # for more info: https://github.com/shu307/mkdocs-nav-weight?tab=readme-ov-file
+ - pub-social:
+ og:
+ enabled: true
+ locale: en_us
+ twitter:
+ enabled: true
+ # for more info: https://github.com/mkusz/mkdocs-publisher
+ - exclude:
+ glob:
+ - dev/* # <- exclude the docs/dev folder from the docs
+ - "*.tmp"
+ - "*.pdf"
+ - "*.gz"
+ regex:
+ - '.*\.(tmp|bin|tar)$'
+ # https://github.com/apenwarr/mkdocs-exclude
extra:
social:
From 8be2b6f38051950e4c49f8b1d5dcde2491e579c0 Mon Sep 17 00:00:00 2001
From: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
Date: Thu, 28 Dec 2023 23:10:58 +0100
Subject: [PATCH 03/42] =?UTF-8?q?=F0=9F=8C=8E:=20Italian=20translation=20u?=
=?UTF-8?q?pdate=20&=20refactor:=20translations=20(#1414)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* italian translation update
* fix: removed some translations
* refactor(Translation)
---
client/src/localization/Translation.tsx | 3 +-
client/src/localization/languages/Ar.tsx | 1 -
client/src/localization/languages/De.tsx | 1 -
client/src/localization/languages/It.tsx | 230 +++++++++++++----------
client/src/localization/languages/Zh.tsx | 1 -
5 files changed, 129 insertions(+), 107 deletions(-)
diff --git a/client/src/localization/Translation.tsx b/client/src/localization/Translation.tsx
index e9826af8f412..e353be293bc2 100644
--- a/client/src/localization/Translation.tsx
+++ b/client/src/localization/Translation.tsx
@@ -57,8 +57,7 @@ if (!String.prototype.format) {
// input: language code in string
// returns an object of translated strings in the language
export const getTranslations = (langCode: string) => {
- const language = languageMap[langCode] || English;
- return language;
+ return languageMap[langCode] || English;
};
// input: language code in string & phrase key in string
diff --git a/client/src/localization/languages/Ar.tsx b/client/src/localization/languages/Ar.tsx
index 85d8f5de5fbf..424f9f2b0cd6 100644
--- a/client/src/localization/languages/Ar.tsx
+++ b/client/src/localization/languages/Ar.tsx
@@ -262,5 +262,4 @@ export default {
com_nav_search_placeholder: 'بحث في الرسائل',
com_nav_setting_general: 'عام',
com_nav_setting_data: 'تحكم في البيانات',
- com_nav_language: 'اللغة',
};
diff --git a/client/src/localization/languages/De.tsx b/client/src/localization/languages/De.tsx
index 7abf98e87c01..ec6fa99d015f 100644
--- a/client/src/localization/languages/De.tsx
+++ b/client/src/localization/languages/De.tsx
@@ -201,5 +201,4 @@ export default {
com_nav_settings: 'Einstellungen',
com_nav_search_placeholder: 'Durchsuche Nachrichten',
com_nav_setting_general: 'Generell',
- com_nav_lang_german: 'Deutsch',
};
diff --git a/client/src/localization/languages/It.tsx b/client/src/localization/languages/It.tsx
index 9c274f541336..d07eb798ab15 100644
--- a/client/src/localization/languages/It.tsx
+++ b/client/src/localization/languages/It.tsx
@@ -3,17 +3,18 @@
export default {
com_ui_examples: 'Esempi',
com_ui_new_chat: 'Nuova Chat',
- com_ui_example_quantum_computing: 'Spiega il computing quantistico in termini semplici',
- com_ui_example_10_year_old_b_day: 'Hai idee creative per il compleanno di un bambino di 10 anni?',
+ com_ui_example_quantum_computing: 'Spiega l\'informatica quantistica in termini semplici',
+ com_ui_example_10_year_old_b_day:
+ 'Hai qualche idea creativa per il compleanno di un bambino di 10 anni?',
com_ui_example_http_in_js: 'Come faccio una richiesta HTTP in Javascript?',
com_ui_capabilities: 'Funzionalità',
- com_ui_capability_remember: 'Ricorda cosa ha detto l\'utente precedentemente nella conversazione',
- com_ui_capability_correction: 'Permette all\'utente di fornire correzioni di follow-up',
+ com_ui_capability_remember: 'Ricorda cosa ha detto l\'utente prima nella conversazione',
+ com_ui_capability_correction: 'Permette all\'utente di fornire correzioni successive',
com_ui_capability_decline_requests: 'Addestrato a rifiutare richieste inappropriate',
com_ui_limitations: 'Limitazioni',
- com_ui_limitation_incorrect_info: 'Può occasionalmente generare informazioni scorrette',
+ com_ui_limitation_incorrect_info: 'Può occasionalmente generare informazioni errate',
com_ui_limitation_harmful_biased:
- 'Può occasionalmente produrre istruzioni dannose o contenuti faziosi',
+ 'Può occasionalmente produrre istruzioni dannose o contenuti di parte',
com_ui_limitation_limited_2021: 'Conoscenza limitata del mondo e degli eventi dopo il 2021',
com_ui_input: 'Input',
com_ui_close: 'Chiudi',
@@ -21,19 +22,19 @@ export default {
com_ui_select_model: 'Seleziona un modello',
com_ui_use_prompt: 'Usa prompt',
com_ui_prev: 'Prec',
- com_ui_next: 'Succ',
- com_ui_stop: 'Stop',
+ com_ui_next: 'Successivo',
+ com_ui_stop: 'Ferma',
com_ui_prompt_templates: 'Modelli di prompt',
com_ui_hide_prompt_templates: 'Nascondi modelli di prompt',
com_ui_showing: 'Mostra',
com_ui_of: 'di',
com_ui_entries: 'Voci',
com_ui_pay_per_call:
- 'Tutte le conversazioni AI in un unico posto. Paga per chiamata e non per mese',
- com_ui_new_footer: 'Tutte le conversazioni AI in un unico posto.',
+ 'Tutte le conversazioni IA in un unico luogo. Paga per chiamata, non per mese',
+ com_ui_new_footer: 'Tutte le conversazioni IA in un unico luogo.',
com_ui_enter: 'Inserisci',
com_ui_submit: 'Invia',
- com_ui_upload_success: 'File caricato con successo',
+ com_ui_upload_success: 'File caricato correttamente',
com_ui_upload_invalid: 'File non valido per il caricamento',
com_ui_cancel: 'Annulla',
com_ui_save: 'Salva',
@@ -53,44 +54,45 @@ export default {
com_ui_delete_conversation: 'Eliminare la chat?',
com_ui_delete_conversation_confirm: 'Questo eliminerà',
com_auth_error_login:
- 'Impossibile accedere con le informazioni fornite. Si prega di controllare le credenziali e riprovare.',
+ 'Impossibile accedere con le informazioni fornite. Per favore controlla le tue credenziali e riprova.',
com_auth_error_login_rl:
- 'Troppo tentativi di accesso in uno breve lasso di tempo. Per favore riprova più tardi.',
+ 'Troppi tentativi di accesso in breve tempo. Per favore riprova più tardi.',
com_auth_error_login_ban:
- 'Il tuo account è stato temporaneamente bloccato dovuto a violazioni del nostro servizio.',
+ 'Il tuo account è stato temporaneamente bloccato a causa della violazione del nostro servizio.',
com_auth_error_login_server:
- 'C\'è stato un errore interno del server. Si prega di attendere qualche istante e riprovare.',
+ 'Si è verificato un errore interno del server. Attendi qualche istante e riprova.',
com_auth_no_account: 'Non hai un account?',
- com_auth_sign_up: 'Iscriviti',
+ com_auth_sign_up: 'Registrati',
com_auth_sign_in: 'Accedi',
com_auth_google_login: 'Accedi con Google',
com_auth_facebook_login: 'Accedi con Facebook',
com_auth_github_login: 'Accedi con Github',
com_auth_discord_login: 'Accedi con Discord',
com_auth_email: 'Email',
- com_auth_email_required: 'Email obbligatoria',
- com_auth_email_min_length: 'L\'email deve avere almeno 6 caratteri',
+ com_auth_email_required: 'L\'email è obbligatoria',
+ com_auth_email_min_length: 'L\'email deve essere lunga almeno 6 caratteri',
com_auth_email_max_length: 'L\'email non dovrebbe essere più lunga di 120 caratteri',
com_auth_email_pattern: 'Devi inserire un indirizzo email valido',
com_auth_email_address: 'Indirizzo email',
com_auth_password: 'Password',
com_auth_password_required: 'La password è obbligatoria',
- com_auth_password_min_length: 'La password deve avere almeno 8 caratteri',
- com_auth_password_max_length: 'La password deve essere più breve di 128 caratteri',
+ com_auth_password_min_length: 'La password deve essere lunga almeno 8 caratteri',
+ com_auth_password_max_length: 'La password deve essere più corta di 128 caratteri',
com_auth_password_forgot: 'Password dimenticata?',
com_auth_password_confirm: 'Conferma password',
- com_auth_password_not_match: 'Le password non coincidono',
+ com_auth_password_not_match: 'Le password non corrispondono',
com_auth_continue: 'Continua',
com_auth_create_account: 'Crea il tuo account',
- com_auth_error_create: 'C\'è stato un errore nel tentativo di registrarti. Per favore riprova.',
+ com_auth_error_create:
+ 'Si è verificato un errore nel tentativo di registrare il tuo account. Per favore riprova.',
com_auth_full_name: 'Nome completo',
com_auth_name_required: 'Il nome è obbligatorio',
- com_auth_name_min_length: 'Il nome deve avere almeno 3 caratteri',
- com_auth_name_max_length: 'Il nome deve essere più breve di 80 caratteri',
- com_auth_username: 'Nome utente (opzionale)',
+ com_auth_name_min_length: 'Il nome deve essere lungo almeno 3 caratteri',
+ com_auth_name_max_length: 'Il nome deve essere più corto di 80 caratteri',
+ com_auth_username: 'Nome utente (facoltativo)',
com_auth_username_required: 'Il nome utente è obbligatorio',
- com_auth_username_min_length: 'Il nome utente deve avere almeno 2 caratteri',
- com_auth_username_max_length: 'Il nome utente deve essere più breve di 20 caratteri',
+ com_auth_username_min_length: 'Il nome utente deve essere lungo almeno 2 caratteri',
+ com_auth_username_max_length: 'Il nome utente deve essere più corto di 20 caratteri',
com_auth_already_have_account: 'Hai già un account?',
com_auth_login: 'Accedi',
com_auth_reset_password: 'Reimposta la tua password',
@@ -99,42 +101,44 @@ export default {
com_auth_to_reset_your_password: 'per reimpostare la tua password.',
com_auth_reset_password_link_sent: 'Email inviata',
com_auth_reset_password_email_sent:
- 'Ti è stata inviata una email con ulteriori istruzioni per reimpostare la password.',
+ 'Ti è stata inviata un\'email con ulteriori istruzioni per reimpostare la tua password.',
com_auth_error_reset_password:
- 'C\'è stato un problema nel reimpostare la password. Non è stato trovato nessun utente con l\'indirizzo email fornito. Per favore riprova.',
- com_auth_reset_password_success: 'Password reimpostata con successo',
+ 'Si è verificato un problema durante il reset della password. Non è stato trovato nessun utente con l\'indirizzo email fornito. Per favore riprova.',
+ com_auth_reset_password_success: 'Reset password avvenuto con successo',
com_auth_login_with_new_password: 'Ora puoi accedere con la tua nuova password.',
- com_auth_error_invalid_reset_token: 'Questo token di reimpostazione password non è più valido.',
+ com_auth_error_invalid_reset_token: 'Questo token di reset password non è più valido.',
com_auth_click_here: 'Clicca qui',
- com_auth_to_try_again: 'per provare di nuovo.',
+ com_auth_to_try_again: 'per riprovare.',
com_auth_submit_registration: 'Invia registrazione',
- com_auth_welcome_back: 'Ben tornato',
- com_endpoint_open_menu: 'Apri menu',
+ com_auth_welcome_back: 'Bentornato',
+ com_endpoint_open_menu: 'Apri il menu',
com_endpoint_bing_enable_sydney: 'Abilita Sydney',
com_endpoint_bing_to_enable_sydney: 'Per abilitare Sydney',
- com_endpoint_bing_jailbreak: 'Forza protezioni',
+ com_endpoint_bing_jailbreak: 'Jailbreak',
com_endpoint_bing_context_placeholder:
- 'Bing può usare fino a 7k token per "contesto", che può referenziare per la conversazione. Il limite specifico non è noto ma potrebbe andare in errore superando i 7k token',
+ 'Bing può usare fino a 7k token per "contesto", che può fare riferimento per la conversazione. Il limite specifico non è noto ma può dare errori superando i 7k token',
com_endpoint_bing_system_message_placeholder:
- 'ATTENZIONE: L\'abuso di questa funzione può farti BANNARE dall\'uso di Bing! Clicca su \'Messaggio di sistema\' per le istruzioni complete e il messaggio predefinito se omesso, che è il preset \'Sydney\' che è considerato sicuro.',
+ 'ATTENZIONE: L\'abuso di questa funzione può farti BLOCCARE da Bing! Fai clic su "Messaggio di sistema" per le istruzioni complete e il messaggio predefinito se omesso, che è il preset "Sydney" considerato sicuro.',
com_endpoint_system_message: 'Messaggio di sistema',
- com_endpoint_default_blank: 'predefinito: vuoto',
- com_endpoint_default_false: 'predefinito: falso',
- com_endpoint_default_creative: 'predefinito: creativo',
- com_endpoint_default_empty: 'predefinito: vuoto',
- com_endpoint_default_with_num: 'predefinito: {0}',
+ com_endpoint_message: 'Messaggio',
+ com_endpoint_message_not_appendable: 'Modifica il tuo messaggio o Rigenera.',
+ com_endpoint_default_blank: 'default: vuoto',
+ com_endpoint_default_false: 'default: falso',
+ com_endpoint_default_creative: 'default: creativo',
+ com_endpoint_default_empty: 'default: vuoto',
+ com_endpoint_default_with_num: 'default: {0}',
com_endpoint_context: 'Contesto',
- com_endpoint_tone_style: 'Stile tono',
+ com_endpoint_tone_style: 'Stile del tono',
com_endpoint_token_count: 'Conteggio token',
com_endpoint_output: 'Output',
com_endpoint_google_temp:
- 'Valori più alti = più casuali, mentre valori più bassi = più mirati e deterministici. Consigliamo di modificare questo o Top P ma non entrambi.',
+ 'Valori più alti = più casuali, mentre valori più bassi = più focalizzati e deterministici. Si consiglia di modificare questo o Top P ma non entrambi.',
com_endpoint_google_topp:
- 'Top-p cambia come il modello seleziona i token per l\'output. I token sono selezionati dai K più probabili (vedi parametro topK) ai meno probabili finché la somma delle loro probabilità equivale al valore top-p.',
+ 'Top-p cambia come il modello seleziona i token per l\'output. I token vengono selezionati dai più probabili K (vedi parametro topK) ai meno probabili fino a che la somma delle loro probabilità eguaglia il valore top-p.',
com_endpoint_google_topk:
- 'Top-k cambia come il modello seleziona i token per l\'output. Un top-k di 1 significa che il token selezionato è il più probabile tra tutti i token nel vocabolario del modello (anche chiamato decodifica greedy), mentre un top-k di 3 significa che il token successivo è selezionato tra i 3 token più probabili (usando temperature).',
+ 'Top-k cambia come il modello seleziona i token per l\'output. Un top-k di 1 significa che il token selezionato è il più probabile tra tutti i token nel vocabolario del modello (chiamato anche decodifica avida), mentre un top-k di 3 significa che il token successivo viene selezionato tra i 3 token più probabili (usando la temperatura).',
com_endpoint_google_maxoutputtokens:
- 'Numero massimo di token che possono essere generati nella risposta. Specifica un valore più basso per risposte più corte e un valore più alto per risposte più lunghe.',
+ 'Numero massimo di token che possono essere generati nella risposta. Specifica un valore inferiore per risposte più brevi e un valore superiore per risposte più lunghe.',
com_endpoint_google_custom_name_placeholder: 'Imposta un nome personalizzato per Google',
com_endpoint_prompt_prefix_placeholder:
'Imposta istruzioni o contesto personalizzati. Ignorato se vuoto.',
@@ -146,41 +150,57 @@ export default {
com_endpoint_top_k: 'Top K',
com_endpoint_max_output_tokens: 'Token output massimi',
com_endpoint_openai_temp:
- 'Valori più alti = più casuali, mentre valori più bassi = più mirati e deterministici. Consigliamo di modificare questo o Top P ma non entrambi.',
+ 'Valori più alti = più casuali, mentre valori più bassi = più focalizzati e deterministici. Si consiglia di modificare questo o Top P ma non entrambi.',
com_endpoint_openai_max:
- 'Il numero massimo di token da generare. La lunghezza totale di token di input e token generati è limitata dalla lunghezza di contesto del modello.',
+ 'Il numero massimo di token da generare. La lunghezza totale dei token di input e generati è limitata dalla lunghezza di contesto del modello.',
com_endpoint_openai_topp:
- 'Un\'alternativa al campionamento con temperatura, chiamata nucleus sampling, dove il modello considera i risultati dei token con la massa di probabilità top_p. Quindi 0.1 significa che vengono considerati solo i token che comprendono il 10% della massa di probabilità in cima.',
+ 'Un\'alternativa al campionamento con temperatura, chiamata nucleus sampling, dove il modello considera i risultati dei token con massa di probabilità top_p. Quindi 0.1 significa che vengono considerati solo i token che comprendono il 10% della massa di probabilità.',
com_endpoint_openai_freq:
- 'Numero tra -2.0 e 2.0. Valori positivi penalizzano nuovi token in base alla loro frequenza esistente nel testo finora, diminuendo la probabilità del modello di ripetere la stessa frase parola per parola.',
+ 'Numero tra -2.0 e 2.0. Valori positivi penalizzano i nuovi token in base alla loro frequenza esistente nel testo finora, diminuendo la probabilità del modello di ripetere la stessa riga verbatim.',
com_endpoint_openai_pres:
- 'Numero tra -2.0 e 2.0. Valori positivi penalizzano nuovi token in base al fatto che appaiano nel testo finora, aumentando la probabilità del modello di parlare di nuovi argomenti.',
+ 'Numero tra -2.0 e 2.0. Valori positivi penalizzano i nuovi token in base al fatto che appaiano nel testo finora, aumentando la probabilità del modello di parlare di nuovi argomenti.',
com_endpoint_openai_custom_name_placeholder: 'Imposta un nome personalizzato per ChatGPT',
com_endpoint_openai_prompt_prefix_placeholder:
- 'Imposta istruzioni personalizzate da includere nel Messaggio di sistema. Predefinito: nessuna',
+ 'Imposta istruzioni personalizzate da includere nel Messaggio di sistema. Predefinito: nessuno',
com_endpoint_anthropic_temp:
- 'Intervallo da 0 a 1. Usa temperature più vicine a 0 per compiti analitici/a scelta multipla e più vicine a 1 per compiti creativi e generativi. Consigliamo di modificare questo o Top P ma non entrambi.',
+ 'Varia da 0 a 1. Usa una temp più vicina a 0 per compiti analitici / a scelta multipla, e più vicina a 1 per compiti creativi e generativi. Si consiglia di modificare questo o Top P ma non entrambi.',
com_endpoint_anthropic_topp:
- 'Top-p cambia come il modello seleziona i token per l\'output. I token sono selezionati dai K più probabili (vedi parametro topK) ai meno probabili finché la somma delle loro probabilità equivale al valore top-p.',
+ 'Top-p cambia come il modello seleziona i token per l\'output. I token vengono selezionati dai più probabili K (vedi parametro topK) ai meno probabili fino a che la somma delle loro probabilità eguaglia il valore top-p.',
com_endpoint_anthropic_topk:
- 'Top-k cambia come il modello seleziona i token per l\'output. Un top-k di 1 significa che il token selezionato è il più probabile tra tutti i token nel vocabolario del modello (anche chiamato decodifica greedy), mentre un top-k di 3 significa che il token successivo è selezionato tra i 3 token più probabili (usando temperature).',
+ 'Top-k cambia come il modello seleziona i token per l\'output. Un top-k di 1 significa che il token selezionato è il più probabile tra tutti i token nel vocabolario del modello (chiamato anche decodifica avida), mentre un top-k di 3 significa che il token successivo viene selezionato tra i 3 token più probabili (usando la temperatura).',
com_endpoint_anthropic_maxoutputtokens:
- 'Numero massimo di token che possono essere generati nella risposta. Specifica un valore più basso per risposte più corte e un valore più alto per risposte più lunghe.',
+ 'Numero massimo di token che possono essere generati nella risposta. Specifica un valore inferiore per risposte più brevi e un valore superiore per risposte più lunghe.',
com_endpoint_anthropic_custom_name_placeholder: 'Imposta un nome personalizzato per Anthropic',
- com_endpoint_frequency_penalty: 'Penalità frequenza',
- com_endpoint_presence_penalty: 'Penalità presenza',
- com_endpoint_plug_use_functions: 'Abilita uso Plugin come funzioni OpenAI',
- com_endpoint_plug_skip_completion: 'Salta fase Completamento',
+ com_endpoint_frequency_penalty: 'Penalità di frequenza',
+ com_endpoint_presence_penalty: 'Penalità di presenza',
+ com_endpoint_plug_use_functions: 'Usa funzioni',
+ com_endpoint_plug_skip_completion: 'Salta completamento',
com_endpoint_disabled_with_tools: 'disabilitato con strumenti',
- com_endpoint_disabled_with_tools_placeholder: 'Disabilitato con Strumenti Selezionati',
+ com_endpoint_disabled_with_tools_placeholder: 'Disabilitato con strumenti selezionati',
com_endpoint_plug_set_custom_instructions_for_gpt_placeholder:
- 'Imposta le istruzioni personalizzate da includere nel Messaggio di sistema. Predefinito: nessuna',
+ 'Imposta istruzioni personalizzate da includere nel Messaggio di sistema. Predefinito: nessuno',
com_endpoint_import: 'Importa',
com_endpoint_set_custom_name:
'Imposta un nome personalizzato, nel caso tu possa trovare questo preset',
+ com_endpoint_preset_delete_confirm: 'Sei sicuro di voler eliminare questo preset?',
+ com_endpoint_preset_clear_all_confirm: 'Sei sicuro di voler eliminare tutti i tuoi preset?',
+ com_endpoint_preset_import: 'Preset importato!',
+ com_endpoint_preset_import_error:
+ 'Si è verificato un errore durante l\'importazione del tuo preset. Per favore riprova.',
+ com_endpoint_preset_save_error:
+ 'Si è verificato un errore durante il salvataggio del tuo preset. Per favore riprova.',
+ com_endpoint_preset_delete_error:
+ 'Si è verificato un errore durante l\'eliminazione del tuo preset. Per favore riprova.',
+ com_endpoint_preset_default_removed: 'non è più il preset predefinito.',
+ com_endpoint_preset_default_item: 'Predefinito:',
+ com_endpoint_preset_default_none: 'Nessun preset predefinito attivo.',
+ com_endpoint_preset_title: 'Preset',
+ com_endpoint_preset_saved: 'Salvato!',
+ com_endpoint_preset_default: 'è ora il preset predefinito.',
com_endpoint_preset: 'preset',
com_endpoint_presets: 'preset',
com_endpoint_preset_selected: 'Preset attivo!',
+ com_endpoint_preset_selected_title: 'Attivo!',
com_endpoint_preset_name: 'Nome preset',
com_endpoint_new_topic: 'Nuovo argomento',
com_endpoint: 'Endpoint',
@@ -194,59 +214,66 @@ export default {
com_endpoint_export: 'Esporta',
com_endpoint_save_as_preset: 'Salva come preset',
com_endpoint_presets_clear_warning:
- 'Sei sicuro di voler cancellare tutti i preset? Questa azione sarà irreversibile.',
+ 'Sei sicuro di voler cancellare tutti i preset? Questa operazione è irreversibile.',
com_endpoint_not_implemented: 'Non implementato',
- com_endpoint_no_presets: 'Nessun preset ancora',
+ com_endpoint_no_presets: 'Nessun preset ancora, usa il pulsante impostazioni per crearne uno',
com_endpoint_not_available: 'Nessun endpoint disponibile',
- com_endpoint_clear_all: 'Cancella tutto',
- com_endpoint_view_options: 'Visualizza opzioni',
+ com_endpoint_view_options: 'Opzioni di visualizzazione',
com_endpoint_save_convo_as_preset: 'Salva conversazione come preset',
- com_endpoint_my_preset: 'Il mio preimpostato',
- com_endpoint_agent_model: 'Modello Agente (Consigliato: GPT-3.5)',
- com_endpoint_completion_model: 'Modello Completamento (Consigliato: GPT-4)',
- com_endpoint_func_hover: 'Abilitare l\'uso dei Plugin come funzioni OpenAI',
+ com_endpoint_my_preset: 'Il mio preset',
+ com_endpoint_agent_model: 'Modello agente (Consigliato: GPT-3.5)',
+ com_endpoint_completion_model: 'Modello completamento (Consigliato: GPT-4)',
+ com_endpoint_func_hover: 'Abilita l\'uso di plugin come funzioni OpenAI',
com_endpoint_skip_hover:
- 'Abilita la possibilità di saltare la fase di completamento, che rivede la risposta finale e le fasi generate',
- com_endpoint_config_key: 'Imposta Chiave API',
- com_endpoint_config_key_for: 'Imposta Chiave API per',
+ 'Abilita il salto del passaggio di completamento, che rivede la risposta finale e i passaggi generati',
+ com_endpoint_config_key: 'Imposta chiave API',
+ com_endpoint_config_placeholder: 'Imposta la tua Chiave nel menu Header per chattare.',
+ com_endpoint_config_key_for: 'Imposta chiave API per',
com_endpoint_config_key_name: 'Chiave',
com_endpoint_config_value: 'Inserisci valore per',
- com_endpoint_config_key_name_placeholder: 'Prima imposta una chiave API',
+ com_endpoint_config_key_name_placeholder: 'Imposta prima la chiave API',
com_endpoint_config_key_encryption: 'La tua chiave verrà crittografata ed eliminata al',
- com_endpoint_config_key_expiry: 'il tempo di scadenza',
- com_endpoint_config_key_import_json_key: 'Importa la chiave JSON dell\'account di servizio',
+ com_endpoint_config_key_expiry: 'tempo di scadenza',
+ com_endpoint_config_click_here: 'Clicca qui',
+ com_endpoint_config_google_service_key: 'Chiave account servizio Google',
+ com_endpoint_config_google_cloud_platform: '(da Google Cloud Platform)',
+ com_endpoint_config_google_api_key: 'Chiave API Google',
+ com_endpoint_config_google_gemini_api: '(API Gemini)',
+ com_endpoint_config_google_api_info:
+ 'Per ottenere la tua chiave API Linguaggio Generativo (per Gemini),',
+ com_endpoint_config_key_import_json_key: 'Importa chiave JSON account di servizio.',
com_endpoint_config_key_import_json_key_success:
- 'Chiave JSON dell\'account di servizio importata correttamente',
+ 'Chiave JSON account di servizio importata con successo',
com_endpoint_config_key_import_json_key_invalid:
- 'Chiave JSON del Service Account non valida, hai importato il file corretto?',
- com_endpoint_config_key_get_edge_key: 'Per ottenere il token di accesso per Bing, accedi a',
+ 'Chiave JSON account di servizio non valida, hai importato il file corretto?',
+ com_endpoint_config_key_get_edge_key: 'Per ottenere il tuo token di accesso per Bing, accedi a',
com_endpoint_config_key_get_edge_key_dev_tool:
- 'Usa gli strumenti di sviluppo o un\'estensione mentre sei loggato nel sito per copiare il contenuto del cookie _U. Se ciò fallisce, segui queste',
- com_endpoint_config_key_edge_instructions: 'Istruzioni',
- com_endpoint_config_key_edge_full_key_string: 'per fornire la stringa di cookie complete.',
+ 'Usa gli strumenti di sviluppo o un\'estensione mentre sei loggato nel sito per copiare il contenuto del cookie _U. Se questo non funziona, segui queste',
+ com_endpoint_config_key_edge_instructions: 'istruzioni',
+ com_endpoint_config_key_edge_full_key_string: 'per fornire le stringhe complete dei cookie.',
com_endpoint_config_key_chatgpt:
- 'Per ottenere il tuo token di accesso per ChatGPT \'Versione gratuita\', accedi a',
+ 'Per ottenere il tuo token di accesso Per ChatGPT "Versione gratuita", accedi a',
com_endpoint_config_key_chatgpt_then_visit: 'poi visita',
com_endpoint_config_key_chatgpt_copy_token: 'Copia token di accesso.',
com_endpoint_config_key_google_need_to: 'Devi',
com_endpoint_config_key_google_vertex_ai: 'Abilitare Vertex AI',
com_endpoint_config_key_google_vertex_api: 'API su Google Cloud, poi',
- com_endpoint_config_key_google_service_account: 'Crea un account di servizio',
+ com_endpoint_config_key_google_service_account: 'Creare un account di servizio',
com_endpoint_config_key_google_vertex_api_role:
- 'Assicurati di fare clic su \'Crea e continua\' per dare almeno il ruolo \'Utente Vertex AI\'. Infine, crea una chiave JSON da importare qui.',
+ 'Assicurati di fare clic su "Crea e continua" per dare almeno il ruolo "Vertex AI User". Infine, crea una chiave JSON da importare qui.',
com_nav_welcome_message: 'Come posso aiutarti oggi?',
- com_nav_auto_scroll: 'Scorrimento automatico',
- com_nav_plugin_store: 'Negozio dei plugin',
+ com_nav_auto_scroll: 'Scorri automaticamente al Più recente all\'apertura',
+ com_nav_plugin_store: 'Negozio plugin',
com_nav_plugin_search: 'Cerca plugin',
com_nav_plugin_auth_error:
- 'Si è verificato un errore durante il tentativo di autenticare questo plugin. Per favore, riprova.',
- com_nav_export_filename: 'Nome del file',
+ 'Si è verificato un errore durante il tentativo di autenticare questo plugin. Per favore riprova.',
+ com_nav_export_filename: 'Nome file',
com_nav_export_filename_placeholder: 'Imposta il nome del file',
com_nav_export_type: 'Tipo',
- com_nav_export_include_endpoint_options: 'Includi opzioni dell\'endpoint',
+ com_nav_export_include_endpoint_options: 'Includi opzioni endpoint',
com_nav_enabled: 'Abilitato',
com_nav_not_supported: 'Non supportato',
- com_nav_export_all_message_branches: 'Esporta tutti i rami dei messaggi',
+ com_nav_export_all_message_branches: 'Esporta tutti i rami di messaggio',
com_nav_export_recursive_or_sequential: 'Ricorsivo o sequenziale?',
com_nav_export_recursive: 'Ricorsivo',
com_nav_export_conversation: 'Esporta conversazione',
@@ -254,20 +281,19 @@ export default {
com_nav_theme_system: 'Sistema',
com_nav_theme_dark: 'Scuro',
com_nav_theme_light: 'Chiaro',
- com_nav_clear: 'Cancella',
- com_nav_clear_all_chats: 'Cancella tutte le chat',
- com_nav_confirm_clear: 'Conferma la cancellazione',
- com_nav_close_sidebar: 'Chiudi la barra laterale',
- com_nav_open_sidebar: 'Apri la barra laterale',
+ com_nav_clear_all_chats: 'Elimina tutte le chat',
+ com_nav_confirm_clear: 'Conferma eliminazione',
+ com_nav_close_sidebar: 'Chiudi sidebar',
+ com_nav_open_sidebar: 'Apri sidebar',
com_nav_send_message: 'Invia messaggio',
- com_nav_log_out: 'Esci',
+ com_nav_log_out: 'Disconnettiti',
com_nav_user: 'UTENTE',
- com_nav_clear_conversation: 'Cancella conversazioni',
+ com_nav_clear_conversation: 'Elimina conversazioni',
com_nav_clear_conversation_confirm_message:
- 'Sei sicuro di voler cancellare tutte le conversazioni? Questa azione è irreversibile.',
- com_nav_help_faq: 'Aiuto & FAQ',
+ 'Sei sicuro di voler eliminare tutte le conversazioni? Questa operazione è irreversibile.',
+ com_nav_help_faq: 'Aiuto e FAQ',
com_nav_settings: 'Impostazioni',
com_nav_search_placeholder: 'Cerca messaggi',
com_nav_setting_general: 'Generale',
- com_nav_setting_data: 'Controllo dei dati',
+ com_nav_setting_data: 'Controlli dati',
};
diff --git a/client/src/localization/languages/Zh.tsx b/client/src/localization/languages/Zh.tsx
index 01ef650af9b8..ffe8552a8420 100644
--- a/client/src/localization/languages/Zh.tsx
+++ b/client/src/localization/languages/Zh.tsx
@@ -246,5 +246,4 @@ export default {
com_nav_search_placeholder: '搜索对话及对话内容',
com_nav_setting_general: '通用',
com_nav_setting_data: '数据管理',
- com_nav_language: '语言',
};
From 443b4912868ba1305a3d92a60fc0a3135b6edb53 Mon Sep 17 00:00:00 2001
From: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
Date: Fri, 29 Dec 2023 23:28:07 +0100
Subject: [PATCH 04/42] feat: allow FWA (#1440)
---
client/index.html | 1 +
index.html | 1 +
2 files changed, 2 insertions(+)
diff --git a/client/index.html b/client/index.html
index 6d6c1dbf5961..dae28cb7057e 100644
--- a/client/index.html
+++ b/client/index.html
@@ -3,6 +3,7 @@
+
LibreChat
+
LibreChat
Date: Sat, 30 Dec 2023 01:28:59 +0300
Subject: [PATCH 05/42] =?UTF-8?q?=F0=9F=8C=8E:=20Update=20Russian=20transl?=
=?UTF-8?q?ations=20(#1413)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Update Russian localization
* Update Ru.tsx
* fix: russian translation typing errors
---
client/src/localization/languages/Ru.tsx | 203 ++++++++++++++---------
1 file changed, 129 insertions(+), 74 deletions(-)
diff --git a/client/src/localization/languages/Ru.tsx b/client/src/localization/languages/Ru.tsx
index f852f4405049..365f93f1da04 100644
--- a/client/src/localization/languages/Ru.tsx
+++ b/client/src/localization/languages/Ru.tsx
@@ -3,10 +3,9 @@
export default {
com_ui_examples: 'Примеры',
com_ui_new_chat: 'Создать чат',
- com_ui_example_quantum_computing: 'Объясните квантовые вычисления простыми словами',
- com_ui_example_10_year_old_b_day:
- 'У вас есть креативные идеи для дня рождения 10-летнего ребенка?',
- com_ui_example_http_in_js: 'Как сделать HTTP-запрос в JavaScript?',
+ com_ui_example_quantum_computing: 'Объясни квантовые вычисления простыми словами',
+ com_ui_example_10_year_old_b_day: 'У тебя есть креативные идеи для дня рождения 10-летнего ребенка?',
+ com_ui_example_http_in_js: 'Как мне сделать HTTP-запрос в JavaScript?',
com_ui_capabilities: 'Возможности',
com_ui_capability_remember: 'Запоминает, что пользователь говорил ранее в разговоре',
com_ui_capability_correction: 'Позволяет пользователю вносить корректировки после ответа',
@@ -18,37 +17,53 @@ export default {
com_ui_limitation_limited_2021: 'Ограниченные знания о мире и событиях после 2021 года',
com_ui_input: 'Ввод',
com_ui_close: 'Закрыть',
- com_ui_clear: 'Очистить',
- com_ui_revoke: 'Отозвать',
- com_ui_revoke_info: 'Отозвать все предоставленные пользователем учетные данные',
com_ui_model: 'Модель',
com_ui_select_model: 'Выберите модель',
- com_ui_use_prompt: 'Использовать подсказку',
+ com_ui_use_prompt: 'Использовать промт',
com_ui_prev: 'Предыдущий',
com_ui_next: 'Следующий',
+ com_ui_stop: 'Остановить генерацию',
+ com_ui_prompt_templates: 'Шаблоны промтов',
+ com_ui_hide_prompt_templates: 'Скрыть шаблоны промтов',
+ com_ui_showing: 'Показано',
+ com_ui_of: 'из',
+ com_ui_entries: 'записей',
+ com_ui_pay_per_call: 'Все AI-разговоры в одном месте. Оплачивайте за вызовы, а не за месяц',
+ com_ui_new_footer: 'Все AI-разговоры в одном месте.',
+ com_ui_enter: 'Ввести',
+ com_ui_submit: 'Отправить',
+ com_ui_upload_success: 'Файл успешно загружен',
+ com_ui_upload_invalid: 'Недопустимый файл для загрузки',
com_ui_cancel: 'Отмена',
com_ui_save: 'Сохранить',
- com_ui_submit: 'Отправить',
+ com_ui_copy_to_clipboard: 'Копировать в буфер обмена',
+ com_ui_copied_to_clipboard: 'Скопировано в буфер обмена',
+ com_ui_regenerate: 'Повторная генерация',
+ com_ui_continue: 'Продолжить',
+ com_ui_edit: 'Редактировать',
+ com_ui_success: 'Успешно',
+ com_ui_all: 'все',
+ com_ui_clear: 'Удалить',
+ com_ui_revoke: 'Отозвать',
+ com_ui_revoke_info: 'Отозвать все предоставленные пользователем учетные данные',
com_ui_confirm_action: 'Подтвердить действие',
+ com_ui_chats: 'чаты',
com_ui_delete: 'Удалить',
com_ui_delete_conversation: 'Удалить чат?',
com_ui_delete_conversation_confirm: 'Будет удален следующий чат: ',
- com_ui_regenerate: 'Повторная генерация',
- com_ui_stop: 'Остановить генерацию',
- com_ui_continue: 'Продолжить',
- com_ui_prompt_templates: 'Шаблоны подсказок',
- com_ui_hide_prompt_templates: 'Скрыть шаблоны подсказок',
- com_ui_showing: 'Показано',
- com_ui_of: 'из',
- com_ui_all: 'все',
- com_ui_entries: 'записей',
- com_ui_pay_per_call: 'Все AI-разговоры в одном месте. Оплачивайте за звонки, а не за месяц',
com_auth_error_login:
'Не удалось войти с предоставленной информацией. Пожалуйста, проверьте ваши учетные данные и попробуйте снова.',
- com_auth_no_account: 'Еще нет аккаунта?',
+ com_auth_error_login_rl:
+ 'Слишком много попыток входа в систему за короткий промежуток времени. Пожалуйста, повторите попытку позже.',
+ com_auth_error_login_ban:
+ 'Ваша учетная запись была временно заблокирована в связи с нарушениями нашего сервиса.',
+ com_auth_error_login_server:
+ 'Произошла внутренняя ошибка сервера. Пожалуйста, подождите несколько минут и повторите попытку.',
+ com_auth_no_account: 'Еще не зарегистрированы?',
com_auth_sign_up: 'Зарегистрироваться',
com_auth_sign_in: 'Войти',
com_auth_google_login: 'Войти с помощью Google',
+ com_auth_facebook_login: 'Войти с помощью Facebook',
com_auth_github_login: 'Войти с помощью Github',
com_auth_discord_login: 'Войти с помощью Discord',
com_auth_email: 'Email',
@@ -74,14 +89,14 @@ export default {
com_auth_name_max_length: 'Имя должно быть короче 80 символов',
com_auth_username: 'Имя пользователя (необязательно)',
com_auth_username_required: 'Имя пользователя обязательно',
- com_auth_username_min_length: 'Имя пользователя должно содержать не менее 3 символов',
+ com_auth_username_min_length: 'Имя пользователя должно содержать не менее 2 символов',
com_auth_username_max_length: 'Имя пользователя должно быть не более 20 символов',
- com_auth_already_have_account: 'Уже есть аккаунт?',
+ com_auth_already_have_account: 'Уже зарегистрированы?',
com_auth_login: 'Войти',
com_auth_reset_password: 'Сбросить пароль',
com_auth_click: 'Нажмите',
com_auth_here: 'ЗДЕСЬ',
- com_auth_to_reset: 'ваш пароль.',
+ com_auth_to_reset_your_password: 'чтобы сбросить ваш пароль.',
com_auth_reset_password_link_sent: 'Письмо отправлено',
com_auth_reset_password_email_sent:
'На вашу почту было отправлено письмо с дальнейшими инструкциями по сбросу пароля.',
@@ -95,14 +110,16 @@ export default {
com_auth_submit_registration: 'Отправить регистрацию',
com_auth_welcome_back: 'Добро пожаловать',
com_endpoint_open_menu: 'Открыть меню',
- com_endpoint_bing_enable_sydney: 'Включить Сидней',
- com_endpoint_bing_to_enable_sydney: 'Чтобы включить Сидней',
+ com_endpoint_bing_enable_sydney: 'Включить Sydney',
+ com_endpoint_bing_to_enable_sydney: 'Чтобы включить Sydney',
com_endpoint_bing_jailbreak: 'Jailbreak',
com_endpoint_bing_context_placeholder:
'Bing может использовать до 7 тысяч токенов для "контекста", на который он может ссылаться в разговоре. Точный предел неизвестен, но превышение 7 тысяч токенов может вызвать ошибки.',
com_endpoint_bing_system_message_placeholder:
- 'ПРЕДУПРЕЖДЕНИЕ: Неправильное использование этой функции может привести к БАНу на использование Bing! Нажмите на "Системное сообщение" для получения полных инструкций и значения по умолчанию, которое является предустановкой "Сидней", считающейся безопасной.',
+ 'ПРЕДУПРЕЖДЕНИЕ: Неправильное использование этой функции может привести к БАНУ на использование Bing! Нажмите на "Системное сообщение" для получения полных инструкций и значения по умолчанию, которое является предустановкой "Sydney", считающейся безопасной.',
com_endpoint_system_message: 'Системное сообщение',
+ com_endpoint_message: 'Сообщение',
+ com_endpoint_message_not_appendable: 'Отредактируйте свое сообщение или перегенерируйте.',
com_endpoint_default_blank: 'по умолчанию: пусто',
com_endpoint_default_false: 'по умолчанию: false',
com_endpoint_default_creative: 'по умолчанию: креативный',
@@ -115,21 +132,20 @@ export default {
com_endpoint_google_temp:
'Более высокие значения = более случайные результаты, более низкие значения = более фокусированные и детерминированные результаты. Мы рекомендуем изменять это или Top P, но не оба значения одновременно.',
com_endpoint_google_topp:
- 'Top P изменяет то, как модель выбирает токены для вывода. Токены выбираются из наиболее вероятных (см. параметр topK) до наименее вероятных, пока сумма их вероятностей не достигнет значения top-p.',
+ 'Top-p изменяет то, как модель выбирает токены для вывода. Токены выбираются из наиболее вероятных K (см. параметр topK) до наименее вероятных, пока сумма их вероятностей не достигнет значения top-p.',
com_endpoint_google_topk:
- 'Top K изменяет то, как модель выбирает токены для вывода. Top K равное 1 означает, что выбирается наиболее вероятный токен из всего словаря модели (так называемое жадное декодирование), а Top K равное 3 означает, что следующий токен выбирается из трех наиболее вероятных токенов (с использованием температуры).',
+ 'Top-k изменяет то, как модель выбирает токены для вывода. Top-k равное 1 означает, что выбирается наиболее вероятный токен из всего словаря модели (так называемое жадное декодирование), а Top-k равное 3 означает, что следующий токен выбирается из трех наиболее вероятных токенов (с использованием температуры).',
com_endpoint_google_maxoutputtokens:
- 'Максимальное количество токенов, которые могут быть сгенерированы в ответе. Укажите меньшее значение для более коротких ответов и большее значение для более длинных ответов.',
- com_endpoint_google_custom_name_placeholder: 'Установите пользовательское имя для Google',
- com_endpoint_google_prompt_prefix_placeholder:
- 'Установите пользовательские инструкции или контекст. Игнорируется, если пусто.',
- com_endpoint_custom_name: 'Пользовательское имя',
- com_endpoint_prompt_prefix: 'Префикс подсказки',
+ ' Максимальное количество токенов, которые могут быть сгенерированы в ответе. Укажите меньшее значение для более коротких ответов и большее значение для более длинных ответов.',
+ com_endpoint_google_custom_name_placeholder: 'Задайте кастомное имя для Google',
+ com_endpoint_prompt_prefix_placeholder: 'Задайте пользовательские инструкции или контекст. Игнорируется, если пусто.',
+ com_endpoint_custom_name: 'Кастомное имя',
+ com_endpoint_prompt_prefix: 'Префикс промта',
com_endpoint_temperature: 'Температура',
com_endpoint_default: 'по умолчанию',
com_endpoint_top_p: 'Top P',
com_endpoint_top_k: 'Top K',
- com_endpoint_max_output_tokens: 'Максимальное количество токенов в выводе',
+ com_endpoint_max_output_tokens: 'Максимальное количество выводимых токенов',
com_endpoint_openai_temp:
'Более высокие значения = более случайные результаты, более низкие значения = более фокусированные и детерминированные результаты. Мы рекомендуем изменять это или Top P, но не оба значения одновременно.',
com_endpoint_openai_max:
@@ -140,9 +156,9 @@ export default {
'Число от -2.0 до 2.0. Положительные значения штрафуют новые токены на основе их частоты в тексте до сих пор, уменьшая вероятность модели повторить ту же строку дословно.',
com_endpoint_openai_pres:
'Число от -2.0 до 2.0. Положительные значения штрафуют новые токены на основе того, появляются ли они в тексте до сих пор, увеличивая вероятность модели говорить о новых темах.',
- com_endpoint_openai_custom_name_placeholder: 'Установите пользовательское имя для ChatGPT',
+ com_endpoint_openai_custom_name_placeholder: 'Задайте кастомное имя для ChatGPT',
com_endpoint_openai_prompt_prefix_placeholder:
- 'Установите пользовательские инструкции для включения в системное сообщение. По умолчанию: нет',
+ 'Задайте кастомные промты для включения в системное сообщение. По умолчанию: нет',
com_endpoint_anthropic_temp:
'Диапазон значений от 0 до 1. Используйте значение temp ближе к 0 для аналитических / множественного выбора и ближе к 1 для креативных и генеративных задач. Мы рекомендуем изменять это или Top P, но не оба значения одновременно.',
com_endpoint_anthropic_topp:
@@ -151,18 +167,36 @@ export default {
'Top K изменяет то, как модель выбирает токены для вывода. Top K равное 1 означает, что выбирается наиболее вероятный токен из всего словаря модели (так называемое жадное декодирование), а Top K равное 3 означает, что следующий токен выбирается из трех наиболее вероятных токенов (с использованием температуры).',
com_endpoint_anthropic_maxoutputtokens:
'Максимальное количество токенов, которые могут быть сгенерированы в ответе. Укажите меньшее значение для более коротких ответов и большее значение для более длинных ответов.',
+ com_endpoint_anthropic_custom_name_placeholder: 'Задайте кастомное имя для Anthropic',
com_endpoint_frequency_penalty: 'Штраф за частоту',
com_endpoint_presence_penalty: 'Штраф за присутствие',
com_endpoint_plug_use_functions: 'Использовать функции',
com_endpoint_plug_skip_completion: 'Пропустить завершение',
- com_endpoint_disabled_with_tools: 'отключено с инструментами',
- com_endpoint_disabled_with_tools_placeholder: 'Отключено с выбранными инструментами',
+ com_endpoint_disabled_with_tools: 'отключено с плагинами',
+ com_endpoint_disabled_with_tools_placeholder: 'Отключено при включённых плагинах',
com_endpoint_plug_set_custom_instructions_for_gpt_placeholder:
- 'Установите пользовательские инструкции для включения в системное сообщение. По умолчанию: нет',
- com_endpoint_set_custom_name: 'Установите пользовательское имя, чтобы найти эту предустановку',
- com_endpoint_preset_name: 'Имя предустановки',
+ 'Задайте кастомные инструкции для включения в системное сообщение. По умолчанию: нет',
+ com_endpoint_import: 'Импортировать',
+ com_endpoint_set_custom_name: 'Задайте кастомное имя на случай, если вы сможете найти эту предустановку :)',
+ com_endpoint_preset_delete_confirm: 'Вы уверены, что хотите удалить этот пресет?',
+ com_endpoint_preset_clear_all_confirm: 'Вы уверены, что хотите удалить все ваши пресеты?',
+ com_endpoint_preset_import: 'Пресет Импортирован!',
+ com_endpoint_preset_import_error: 'Произошла ошибка при импорте вашего пресета. Пожалуйста, попробуйте еще раз.',
+ com_endpoint_preset_save_error: 'Произошла ошибка при сохранении вашего пресета. Пожалуйста, попробуйте еще раз.',
+ com_endpoint_preset_delete_error: 'Произошла ошибка при удалении вашего пресета. Пожалуйста, попробуйте еще раз.',
+ com_endpoint_preset_default_removed: 'больше не пресет по умолчанию.',
+ com_endpoint_preset_default_item: 'По умолчанию:',
+ com_endpoint_preset_default_none: 'Нет активных пресетов По умолчанию.',
+ com_endpoint_preset_title: 'Пресет',
+ com_endpoint_preset_saved: 'Сохранено!',
+ com_endpoint_preset_default: 'теперь пресет По умолчаанию.',
+ com_endpoint_preset: 'пресет',
+ com_endpoint_presets: 'пресеты',
+ com_endpoint_preset_selected: 'Пресет Активирован!',
+ com_endpoint_preset_selected_title: 'Активирован!',
+ com_endpoint_preset_name: 'Имя пресета',
com_endpoint_new_topic: 'Новая тема',
- com_endpoint: 'Конечная точка',
+ com_endpoint: 'Эндпоинт',
com_endpoint_hide: 'Скрыть',
com_endpoint_show: 'Показать',
com_endpoint_examples: 'Примеры',
@@ -171,41 +205,65 @@ export default {
com_endpoint_show_what_settings: 'Показать настройки {0}',
com_endpoint_save: 'Сохранить',
com_endpoint_export: 'Экспортировать',
- com_endpoint_import: 'Импортировать',
- com_endpoint_save_as_preset: 'Сохранить как предустановку',
- com_endpoint_not_implemented: 'Не реализовано',
- com_endpoint_no_presets: 'Пока нет предустановок',
- com_endpoint_not_available: 'Нет доступных конечных точек',
- com_endpoint_clear_all: 'Очистить все',
- com_endpoint_view_options: 'Просмотреть параметры',
- com_endpoint_save_convo_as_preset: 'Сохранить разговор как предустановку',
+ com_endpoint_save_as_preset: 'Сохранить как Пресет',
com_endpoint_presets_clear_warning:
- 'Вы уверены, что хотите очистить все предустановки? Эти действия необратимы, и восстановление невозможно.',
- com_endpoint_presets: 'предустановки',
- com_endpoint_my_preset: 'Моя предустановка',
- com_endpoint_config_key: 'Установить ключ API',
- com_endpoint_config_key_for: 'Установить ключ API для',
- com_endpoint_config_key_name: 'Ключ',
- com_endpoint_config_value: 'Введите значение для',
- com_endpoint_config_key_name_placeholder: 'Установите сначала ключ API',
- com_endpoint_config_key_import_json_key: 'Импортировать JSON-ключ учетной записи.',
+ 'Вы уверены, что хотите удалить все пресеты? Это действие необратимо и восстановление невозможно.',
+ com_endpoint_not_implemented: 'Не реализовано',
+ com_endpoint_no_presets: 'Пока нет пресетов, используйте кнопку настроек чтобы создать его',
+ com_endpoint_not_available: 'Нет доступных эндпоинтов',
+ com_endpoint_view_options: 'Просмотреть Настройки',
+ com_endpoint_save_convo_as_preset: 'Сохранить текущий разговор как Пресет',
+ com_endpoint_my_preset: 'Мой Пресет',
com_endpoint_agent_model: 'Модель агента (Рекомендуется: GPT-3.5)',
com_endpoint_completion_model: 'Модель завершения (Рекомендуется: GPT-4)',
- com_endpoint_func_hover: 'Включить использование плагинов в качестве функций OpenAI',
+ com_endpoint_func_hover: 'Включить использование плагинов как функции OpenAI',
com_endpoint_skip_hover:
'Пропустить этап завершения, который проверяет окончательный ответ и сгенерированные шаги',
- com_endpoint_config_token: 'Токен конфигурации',
+ com_endpoint_config_key: 'Указать ключ к API',
+ com_endpoint_config_placeholder: 'Укажите ваш ключ к API в меню сверху для начала разговора.',
+ com_endpoint_config_key_for: 'Установить ключ к API для',
+ com_endpoint_config_key_name: 'Ключ',
+ com_endpoint_config_value: 'Введите значение для',
+ com_endpoint_config_key_name_placeholder: 'Сначала укажите ключ к API',
+ com_endpoint_config_key_encryption: 'Ваш ключ зашифрован и будет удалён',
+ com_endpoint_config_key_expiry: 'срок действия',
+ com_endpoint_config_click_here: 'Нажми Здесь',
+ com_endpoint_config_google_service_key: 'Google Service Account Key',
+ com_endpoint_config_google_cloud_platform: '(из Google Cloud Platform)',
+ com_endpoint_config_google_api_key: 'Google API Key',
+ com_endpoint_config_google_gemini_api: '(Gemini API)',
+ com_endpoint_config_google_api_info: 'Чтобы получить ключ к API Generative Language (для Gemini),',
+ com_endpoint_config_key_import_json_key: 'Импортировать Service Account JSON Key.',
+ com_endpoint_config_key_import_json_key_success: 'Успешно Импортирован Service Account JSON Key',
+ com_endpoint_config_key_import_json_key_invalid:
+ 'Некорректный Service Account JSON Key, Вы импортировали верный файл?',
+ com_endpoint_config_key_get_edge_key: 'Чтобы получить ваш токен доступа к Bing, войдите в',
+ com_endpoint_config_key_get_edge_key_dev_tool:
+ 'Пока вы на сайте, используйте dev tools или расширение чтобы скопировать содержимое куки _U. Если не получается, следуйте этим',
+ com_endpoint_config_key_edge_instructions: 'инструкциям',
+ com_endpoint_config_key_edge_full_key_string: 'чтобы получить все строки cookie.',
+ com_endpoint_config_key_chatgpt: 'Чтобы получить токен доступа к "Бесплатной Версии" ChatGPT, войдите в',
+ com_endpoint_config_key_chatgpt_then_visit: 'затем посетите',
+ com_endpoint_config_key_chatgpt_copy_token: 'Скопируйте токен доступа.',
+ com_endpoint_config_key_google_need_to: 'Вам нужно',
+ com_endpoint_config_key_google_vertex_ai: 'Активировать Vertex AI',
+ com_endpoint_config_key_google_vertex_api: 'API в Google Cloud, после',
+ com_endpoint_config_key_google_service_account: 'Создать Service Account',
+ com_endpoint_config_key_google_vertex_api_role:
+ 'Убедитесь что нажали на \'Create and Continue\' чтобы получить как минимум \'Vertex AI User\'. Наконец, создайте JSON-ключ чтобы импортировать его сюда.',
+ com_nav_welcome_message: 'Чем я могу помочь вам сегодня?',
+ com_nav_auto_scroll: 'Автоматически проматывать к самым новым сообщениям при открытии',
com_nav_plugin_store: 'Магазин плагинов',
com_nav_plugin_search: 'Поиск плагинов',
com_nav_plugin_auth_error:
'При попытке аутентификации этого плагина произошла ошибка. Пожалуйста, попробуйте еще раз.',
com_nav_export_filename: 'Имя файла',
- com_nav_export_filename_placeholder: 'Установите имя файла',
+ com_nav_export_filename_placeholder: 'Задайте имя файла',
com_nav_export_type: 'Тип',
- com_nav_export_include_endpoint_options: 'Включить параметры конечной точки',
+ com_nav_export_include_endpoint_options: 'Включить параметры эндпоинта',
com_nav_enabled: 'Включено',
com_nav_not_supported: 'Не поддерживается',
- com_nav_export_all_message_branches: 'Экспортировать все ветви сообщений',
+ com_nav_export_all_message_branches: 'Экспортировать все ветки сообщений',
com_nav_export_recursive_or_sequential: 'Рекурсивно или последовательно?',
com_nav_export_recursive: 'Рекурсивно',
com_nav_export_conversation: 'Экспортировать разговор',
@@ -213,22 +271,19 @@ export default {
com_nav_theme_system: 'Системная',
com_nav_theme_dark: 'Темная',
com_nav_theme_light: 'Светлая',
- com_nav_language: 'Локализация (Альфа)',
- com_nav_clear: 'Очистить',
- com_nav_clear_all_chats: 'Очистить все чаты',
- com_nav_confirm_clear: 'Подтвердить очистку',
- com_nav_auto_scroll: 'Автоматическая прокрутка к новым сообщениям в режиме открытия',
+ com_nav_clear_all_chats: 'Удалить все чаты',
+ com_nav_confirm_clear: 'Подтвердить удаление',
com_nav_close_sidebar: 'Закрыть боковую панель',
com_nav_open_sidebar: 'Открыть боковую панель',
com_nav_send_message: 'Отправить сообщение',
com_nav_log_out: 'Выйти',
com_nav_user: 'ПОЛЬЗОВАТЕЛЬ',
- com_nav_clear_conversation: 'Очистить разговоры',
+ com_nav_clear_conversation: 'Удалить разговоры',
com_nav_clear_conversation_confirm_message:
- 'Вы уверены, что хотите очистить все разговоры? Это действие нельзя отменить.',
- com_nav_help_faq: 'Помощь и часто задаваемые вопросы',
- com_nav_setting_data: 'Управление данными',
+ 'Вы уверены, что хотите удалить все разговоры? Это действие нельзя отменить.',
+ com_nav_help_faq: 'Помощь и ЧаВо',
com_nav_settings: 'Настройки',
com_nav_search_placeholder: 'Поиск сообщений',
com_nav_setting_general: 'Общие',
+ com_nav_setting_data: 'Управление данными',
};
From c3d5a08b262ad382184ab098bd392154e57c2c98 Mon Sep 17 00:00:00 2001
From: Danny Avila <110412045+danny-avila@users.noreply.github.com>
Date: Fri, 29 Dec 2023 20:20:57 -0500
Subject: [PATCH 06/42] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Prevent=20Unnecessa?=
=?UTF-8?q?ry=20Cloning=20of=20Symbols=20in=20Log=20Object=20(#1455)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
fix(api/config/parsers): prevent cloning of unnecessary symbols within log object by using `klona` instead of `klona/full`, handle symbols edge case, log parsing errors, and use spaces instead of tab for cleaner logs
---
api/config/parsers.js | 108 +++++++++++++++++++++++++-----------------
1 file changed, 65 insertions(+), 43 deletions(-)
diff --git a/api/config/parsers.js b/api/config/parsers.js
index 4f94d6e4d767..59685eab0bf3 100644
--- a/api/config/parsers.js
+++ b/api/config/parsers.js
@@ -1,11 +1,16 @@
+const { klona } = require('klona');
const winston = require('winston');
const traverse = require('traverse');
-const { klona } = require('klona/full');
const SPLAT_SYMBOL = Symbol.for('splat');
const MESSAGE_SYMBOL = Symbol.for('message');
-const sensitiveKeys = [/^(sk-)[^\s]+/, /(Bearer )[^\s]+/, /(api-key:? )[^\s]+/, /(key=)[^\s]+/];
+const sensitiveKeys = [
+ /^(sk-)[^\s]+/, // OpenAI API key pattern
+ /(Bearer )[^\s]+/, // Header: Bearer token pattern
+ /(api-key:? )[^\s]+/, // Header: API key pattern
+ /(key=)[^\s]+/, // URL query param: sensitive key pattern (Google)
+];
/**
* Determines if a given value string is sensitive and returns matching regex patterns.
@@ -102,55 +107,72 @@ const condenseArray = (item) => {
*/
const debugTraverse = winston.format.printf(({ level, message, timestamp, ...metadata }) => {
let msg = `${timestamp} ${level}: ${truncateLongStrings(message?.trim(), 150)}`;
+ try {
+ if (level !== 'debug') {
+ return msg;
+ }
- if (level !== 'debug') {
- return msg;
- }
+ if (!metadata) {
+ return msg;
+ }
- if (!metadata) {
- return msg;
- }
+ const debugValue = metadata[SPLAT_SYMBOL]?.[0];
- const debugValue = metadata[SPLAT_SYMBOL]?.[0];
+ if (!debugValue) {
+ return msg;
+ }
- if (!debugValue) {
- return msg;
- }
+ if (debugValue && Array.isArray(debugValue)) {
+ msg += `\n${JSON.stringify(debugValue.map(condenseArray))}`;
+ return msg;
+ }
- if (debugValue && Array.isArray(debugValue)) {
- msg += `\n${JSON.stringify(debugValue.map(condenseArray))}`;
- return msg;
- }
+ if (typeof debugValue !== 'object') {
+ return (msg += ` ${debugValue}`);
+ }
- if (typeof debugValue !== 'object') {
- return (msg += ` ${debugValue}`);
- }
+ msg += '\n{';
- msg += '\n{';
-
- const copy = klona(metadata);
- traverse(copy).forEach(function (value) {
- const parent = this.parent;
- const parentKey = `${parent && parent.notRoot ? parent.key + '.' : ''}`;
- const tabs = `${parent && parent.notRoot ? '\t\t' : '\t'}`;
- if (this.isLeaf && typeof value === 'string') {
- const truncatedText = truncateLongStrings(value);
- msg += `\n${tabs}${parentKey}${this.key}: ${JSON.stringify(truncatedText)},`;
- } else if (this.notLeaf && Array.isArray(value) && value.length > 0) {
- const currentMessage = `\n${tabs}// ${value.length} ${this.key.replace(/s$/, '')}(s)`;
- this.update(currentMessage, true);
- msg += currentMessage;
- const stringifiedArray = value.map(condenseArray);
- msg += `\n${tabs}${parentKey}${this.key}: [${stringifiedArray}],`;
- } else if (this.isLeaf && typeof value === 'function') {
- msg += `\n${tabs}${parentKey}${this.key}: function,`;
- } else if (this.isLeaf) {
- msg += `\n${tabs}${parentKey}${this.key}: ${value},`;
- }
- });
+ const copy = klona(metadata);
+ traverse(copy).forEach(function (value) {
+ if (typeof this?.key === 'symbol') {
+ return;
+ }
+
+ let _parentKey = '';
+ const parent = this.parent;
+
+ if (typeof parent?.key !== 'symbol' && parent?.key) {
+ _parentKey = parent.key;
+ }
- msg += '\n}';
- return msg;
+ const parentKey = `${parent && parent.notRoot ? _parentKey + '.' : ''}`;
+
+ const tabs = `${parent && parent.notRoot ? ' ' : ' '}`;
+
+ const currentKey = this?.key ?? 'unknown';
+
+ if (this.isLeaf && typeof value === 'string') {
+ const truncatedText = truncateLongStrings(value);
+ msg += `\n${tabs}${parentKey}${currentKey}: ${JSON.stringify(truncatedText)},`;
+ } else if (this.notLeaf && Array.isArray(value) && value.length > 0) {
+ const currentMessage = `\n${tabs}// ${value.length} ${currentKey.replace(/s$/, '')}(s)`;
+ this.update(currentMessage, true);
+ msg += currentMessage;
+ const stringifiedArray = value.map(condenseArray);
+ msg += `\n${tabs}${parentKey}${currentKey}: [${stringifiedArray}],`;
+ } else if (this.isLeaf && typeof value === 'function') {
+ msg += `\n${tabs}${parentKey}${currentKey}: function,`;
+ } else if (this.isLeaf) {
+ msg += `\n${tabs}${parentKey}${currentKey}: ${value},`;
+ }
+ });
+
+ msg += '\n}';
+ return msg;
+ } catch (e) {
+ return (msg += `\n[LOGGER PARSING ERROR] ${e.message}`);
+ }
});
module.exports = {
From bd4d23d31448e0314dee7e68cfa45de5434ef7e1 Mon Sep 17 00:00:00 2001
From: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
Date: Sat, 30 Dec 2023 02:42:04 +0100
Subject: [PATCH 07/42] =?UTF-8?q?=F0=9F=9A=AB=F0=9F=94=8D=20feat:=20disall?=
=?UTF-8?q?ow=20search=20indexing=20(#1409)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: disallow search indexing
* Update index.js
* Update .env.example
* added middleware
---
.env.example | 3 +++
api/server/index.js | 2 ++
api/server/middleware/index.js | 2 ++
api/server/middleware/noIndex.js | 11 +++++++++++
4 files changed, 18 insertions(+)
create mode 100644 api/server/middleware/noIndex.js
diff --git a/.env.example b/.env.example
index 822bb2d669bc..c3c62becd532 100644
--- a/.env.example
+++ b/.env.example
@@ -24,9 +24,12 @@ MONGO_URI=mongodb://127.0.0.1:27017/LibreChat
DOMAIN_CLIENT=http://localhost:3080
DOMAIN_SERVER=http://localhost:3080
+NO_INDEX=true
+
#===============#
# Debug Logging #
#===============#
+
DEBUG_LOGGING=true
DEBUG_CONSOLE=false
diff --git a/api/server/index.js b/api/server/index.js
index afe9d1047a7b..230f8e79d95c 100644
--- a/api/server/index.js
+++ b/api/server/index.js
@@ -8,6 +8,7 @@ const errorController = require('./controllers/ErrorController');
const configureSocialLogins = require('./socialLogins');
const { connectDb, indexSync } = require('~/lib/db');
const { logger } = require('~/config');
+const noIndex = require('./middleware/noIndex');
const paths = require('~/config/paths');
const routes = require('./routes');
@@ -28,6 +29,7 @@ const startServer = async () => {
app.locals.config = paths;
// Middleware
+ app.use(noIndex);
app.use(errorController);
app.use(express.json({ limit: '3mb' }));
app.use(mongoSanitize());
diff --git a/api/server/middleware/index.js b/api/server/middleware/index.js
index 553f2c663abc..0d878d4c9026 100644
--- a/api/server/middleware/index.js
+++ b/api/server/middleware/index.js
@@ -12,6 +12,7 @@ const concurrentLimiter = require('./concurrentLimiter');
const validateMessageReq = require('./validateMessageReq');
const buildEndpointOption = require('./buildEndpointOption');
const validateRegistration = require('./validateRegistration');
+const noIndex = require('./noIndex');
module.exports = {
...abortMiddleware,
@@ -28,4 +29,5 @@ module.exports = {
validateMessageReq,
buildEndpointOption,
validateRegistration,
+ noIndex,
};
diff --git a/api/server/middleware/noIndex.js b/api/server/middleware/noIndex.js
new file mode 100644
index 000000000000..c4d7b55f2ded
--- /dev/null
+++ b/api/server/middleware/noIndex.js
@@ -0,0 +1,11 @@
+const noIndex = (req, res, next) => {
+ const shouldNoIndex = process.env.NO_INDEX ? process.env.NO_INDEX === 'true' : true;
+
+ if (shouldNoIndex) {
+ res.setHeader('X-Robots-Tag', 'noindex');
+ }
+
+ next();
+};
+
+module.exports = noIndex;
From f19f5dca8e83c386021260c93f20820458cf105f Mon Sep 17 00:00:00 2001
From: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
Date: Sat, 30 Dec 2023 03:42:19 +0100
Subject: [PATCH 08/42] =?UTF-8?q?=F0=9F=94=A5=F0=9F=9A=80=20feat:=20CDN=20?=
=?UTF-8?q?(Firebase)=20&=20feat:=20account=20section=20(#1438)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* localization + api-endpoint
* docs: added firebase documentation
* chore: icons
* chore: SettingsTabs
* feat: account pannel; fix: gear icons
* docs: position update
* feat: firebase
* feat: plugin support
* route
* fixed bugs with firebase and moved a lot of files
* chore(DALLE3): using UUID v4
* feat: support for social strategies; moved '/images' path
* fix: data ignored
* gitignore update
* docs: update firebase guide
* refactor: Firebase
- use singleton pattern for firebase initialization, initially on server start
- reorganize imports, move firebase specific files to own service under Files
- rename modules to remove 'avatar' redundancy
- fix imports based on changes
* ci(DALLE/DALLE3): fix tests to use logger and new expected outputs, add firebase tests
* refactor(loadToolWithAuth): pass userId to tool as field
* feat(images/parse): feat: Add URL Image Basename Extraction
Implement a new module to extract the basename of an image from a given URL. This addition includes the function, which parses the URL and retrieves the basename using the Node.js 'url' and 'path' modules. The function is documented with JSDoc comments for better maintainability and understanding. This feature enhances the application's ability to handle and process image URLs efficiently.
* refactor(addImages): function to use a more specific regular expression for observedImagePath based on the generated image markdown standard across the app
* refactor(DALLE/DALLE3): utilize `getImageBasename` and `this.userId`; fix: pass correct image path to firebase url helper
* fix(addImages): make more general to match any image markdown descriptor
* fix(parse/getImageBasename): test result of this function for an actual image basename
* ci(DALLE3): mock getImageBasename
* refactor(AuthContext): use Recoil atom state for user
* feat: useUploadAvatarMutation, react-query hook for avatar upload
* fix(Toast): stack z-order of Toast over all components (1000)
* refactor(showToast): add optional status field to avoid importing NotificationSeverity on each use of the function
* refactor(routes/avatar): remove unnecessary get route, get userId from req.user.id, require auth on POST request
* chore(uploadAvatar): TODO: remove direct use of Model, `User`
* fix(client): fix Spinner imports
* refactor(Avatar): use react-query hook, Toast, remove unnecessary states, add optimistic UI to upload
* fix(avatar/localStrategy): correctly save local profile picture and cache bust for immediate rendering; fix: firebase init info message (only show once)
* fix: use `includes` instead of `endsWith` for checking manual query of avatar image path in case more queries are appended (as is done in avatar/localStrategy)
---------
Co-authored-by: Danny Avila
---
.env.example | 11 +
.gitignore | 4 +-
api/app/clients/output_parsers/addImages.js | 6 +-
api/app/clients/tools/DALL-E.js | 57 +-
api/app/clients/tools/structured/DALLE3.js | 49 +-
.../tools/structured/specs/DALLE3.spec.js | 74 +-
api/app/clients/tools/util/handleTools.js | 6 +-
api/package.json | 1 +
api/server/index.js | 2 +
api/server/routes/files/avatar.js | 34 +
api/server/routes/files/index.js | 1 +
api/server/services/Files/Firebase/images.js | 45 +
api/server/services/Files/Firebase/index.js | 7 +
.../services/Files/Firebase/initialize.js | 42 +
.../Files/images/avatar/firebaseStrategy.js | 29 +
.../Files/images/avatar/localStrategy.js | 32 +
.../Files/images/avatar/uploadAvatar.js | 63 ++
api/server/services/Files/images/index.js | 4 +
api/server/services/Files/images/parse.js | 27 +
api/strategies/discordStrategy.js | 63 +-
api/strategies/facebookStrategy.js | 57 +-
api/strategies/githubStrategy.js | 53 +-
api/strategies/googleStrategy.js | 53 +-
client/src/App.jsx | 2 +-
client/src/common/types.ts | 1 +
client/src/components/Chat/ChatView.tsx | 2 +-
client/src/components/Nav/Nav.tsx | 2 +-
client/src/components/Nav/NavLinks.tsx | 2 +-
client/src/components/Nav/Settings.tsx | 21 +-
.../Nav/SettingsTabs/Account/Account.tsx | 18 +
.../Nav/SettingsTabs/Account/Avatar.tsx | 145 +++
.../Nav/SettingsTabs/{ => Data}/Data.tsx | 2 +-
.../{ => General}/AutoScrollSwitch.spec.tsx | 0
.../{ => General}/AutoScrollSwitch.tsx | 0
.../{ => General}/ClearChatsButton.spec.tsx | 0
.../SettingsTabs/{ => General}/General.tsx | 2 +-
.../{ => General}/LangSelector.spec.tsx | 0
.../{ => General}/ThemeSelector.spec.tsx | 0
.../src/components/Nav/SettingsTabs/index.ts | 9 +-
client/src/components/svg/GearIcon.tsx | 16 +-
client/src/components/svg/UserIcon.tsx | 15 +-
client/src/components/svg/index.ts | 1 +
client/src/data-provider/mutations.ts | 17 +
client/src/hooks/AuthContext.tsx | 10 +-
client/src/hooks/useToast.ts | 8 +-
client/src/localization/languages/Eng.tsx | 9 +-
client/src/localization/languages/It.tsx | 7 +-
client/src/store/user.ts | 6 +-
docs/features/bing_jailbreak.md | 2 +-
docs/features/firebase.md | 74 ++
docs/features/index.md | 1 +
docs/features/logging_system.md | 2 +-
docs/features/manage_your_database.md | 2 +-
docs/features/pandoranext.md | 2 +-
package-lock.json | 902 +++++++++++++++++-
packages/data-provider/src/api-endpoints.ts | 2 +
packages/data-provider/src/data-service.ts | 4 +
packages/data-provider/src/keys.ts | 1 +
packages/data-provider/src/types/files.ts | 10 +
59 files changed, 1850 insertions(+), 167 deletions(-)
create mode 100644 api/server/routes/files/avatar.js
create mode 100644 api/server/services/Files/Firebase/images.js
create mode 100644 api/server/services/Files/Firebase/index.js
create mode 100644 api/server/services/Files/Firebase/initialize.js
create mode 100644 api/server/services/Files/images/avatar/firebaseStrategy.js
create mode 100644 api/server/services/Files/images/avatar/localStrategy.js
create mode 100644 api/server/services/Files/images/avatar/uploadAvatar.js
create mode 100644 api/server/services/Files/images/parse.js
create mode 100644 client/src/components/Nav/SettingsTabs/Account/Account.tsx
create mode 100644 client/src/components/Nav/SettingsTabs/Account/Avatar.tsx
rename client/src/components/Nav/SettingsTabs/{ => Data}/Data.tsx (98%)
rename client/src/components/Nav/SettingsTabs/{ => General}/AutoScrollSwitch.spec.tsx (100%)
rename client/src/components/Nav/SettingsTabs/{ => General}/AutoScrollSwitch.tsx (100%)
rename client/src/components/Nav/SettingsTabs/{ => General}/ClearChatsButton.spec.tsx (100%)
rename client/src/components/Nav/SettingsTabs/{ => General}/General.tsx (99%)
rename client/src/components/Nav/SettingsTabs/{ => General}/LangSelector.spec.tsx (100%)
rename client/src/components/Nav/SettingsTabs/{ => General}/ThemeSelector.spec.tsx (100%)
create mode 100644 docs/features/firebase.md
diff --git a/.env.example b/.env.example
index c3c62becd532..0c9d303d6ccf 100644
--- a/.env.example
+++ b/.env.example
@@ -281,6 +281,17 @@ EMAIL_PASSWORD=
EMAIL_FROM_NAME=
EMAIL_FROM=noreply@librechat.ai
+#========================#
+# Firebase CDN #
+#========================#
+
+FIREBASE_API_KEY=
+FIREBASE_AUTH_DOMAIN=
+FIREBASE_PROJECT_ID=
+FIREBASE_STORAGE_BUCKET=
+FIREBASE_MESSAGING_SENDER_ID=
+FIREBASE_APP_ID=
+
#==================================================#
# Others #
#==================================================#
diff --git a/.gitignore b/.gitignore
index af92a1f2daf3..f360cbba0acb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,4 +82,6 @@ data.ms/*
auth.json
/packages/ux-shared/
-/images
\ No newline at end of file
+/images
+
+!client/src/components/Nav/SettingsTabs/Data/
\ No newline at end of file
diff --git a/api/app/clients/output_parsers/addImages.js b/api/app/clients/output_parsers/addImages.js
index 38ceb9a68609..ec04bcac86cd 100644
--- a/api/app/clients/output_parsers/addImages.js
+++ b/api/app/clients/output_parsers/addImages.js
@@ -60,12 +60,10 @@ function addImages(intermediateSteps, responseMessage) {
if (!observation || !observation.includes('![')) {
return;
}
- const observedImagePath = observation.match(/\(\/images\/.*\.\w*\)/g);
+ const observedImagePath = observation.match(/!\[.*\]\([^)]*\)/g);
if (observedImagePath && !responseMessage.text.includes(observedImagePath[0])) {
responseMessage.text += '\n' + observation;
- if (process.env.DEBUG_PLUGINS) {
- logger.debug('[addImages] added image from intermediateSteps:', observation);
- }
+ logger.debug('[addImages] added image from intermediateSteps:', observation);
}
});
}
diff --git a/api/app/clients/tools/DALL-E.js b/api/app/clients/tools/DALL-E.js
index 88a7cf850ac2..387294a1cbb6 100644
--- a/api/app/clients/tools/DALL-E.js
+++ b/api/app/clients/tools/DALL-E.js
@@ -4,8 +4,15 @@ const fs = require('fs');
const path = require('path');
const OpenAI = require('openai');
// const { genAzureEndpoint } = require('~/utils/genAzureEndpoints');
+const { v4: uuidv4 } = require('uuid');
const { Tool } = require('langchain/tools');
const { HttpsProxyAgent } = require('https-proxy-agent');
+const {
+ saveImageToFirebaseStorage,
+ getFirebaseStorageImageUrl,
+ getFirebaseStorage,
+} = require('~/server/services/Files/Firebase');
+const { getImageBasename } = require('~/server/services/Files/images');
const extractBaseURL = require('~/utils/extractBaseURL');
const saveImageFromUrl = require('./saveImageFromUrl');
const { logger } = require('~/config');
@@ -15,7 +22,9 @@ class OpenAICreateImage extends Tool {
constructor(fields = {}) {
super();
+ this.userId = fields.userId;
let apiKey = fields.DALLE_API_KEY || this.getApiKey();
+
const config = { apiKey };
if (DALLE_REVERSE_PROXY) {
config.baseURL = extractBaseURL(DALLE_REVERSE_PROXY);
@@ -24,7 +33,6 @@ class OpenAICreateImage extends Tool {
if (PROXY) {
config.httpAgent = new HttpsProxyAgent(PROXY);
}
-
// let azureKey = fields.AZURE_API_KEY || process.env.AZURE_API_KEY;
// if (azureKey) {
@@ -97,12 +105,11 @@ Guidelines:
throw new Error('No image URL returned from OpenAI API.');
}
- const regex = /img-[\w\d]+.png/;
- const match = theImageUrl.match(regex);
- let imageName = '1.png';
+ const imageBasename = getImageBasename(theImageUrl);
+ let imageName = `image_${uuidv4()}.png`;
- if (match) {
- imageName = match[0];
+ if (imageBasename) {
+ imageName = imageBasename;
logger.debug('[DALL-E]', { imageName }); // Output: img-lgCf7ppcbhqQrz6a5ear6FOb.png
} else {
logger.debug('[DALL-E] No image name found in the string.', {
@@ -111,7 +118,18 @@ Guidelines:
});
}
- this.outputPath = path.resolve(__dirname, '..', '..', '..', '..', 'client', 'public', 'images');
+ this.outputPath = path.resolve(
+ __dirname,
+ '..',
+ '..',
+ '..',
+ '..',
+ 'client',
+ 'public',
+ 'images',
+ this.userId,
+ );
+
const appRoot = path.resolve(__dirname, '..', '..', '..', '..', 'client');
this.relativeImageUrl = path.relative(appRoot, this.outputPath);
@@ -120,14 +138,25 @@ Guidelines:
fs.mkdirSync(this.outputPath, { recursive: true });
}
- try {
- await saveImageFromUrl(theImageUrl, this.outputPath, imageName);
- this.result = this.getMarkdownImageUrl(imageName);
- } catch (error) {
- logger.error('Error while saving the DALL-E image:', error);
- this.result = theImageUrl;
+ const storage = getFirebaseStorage();
+ if (storage) {
+ try {
+ await saveImageToFirebaseStorage(this.userId, theImageUrl, imageName);
+ this.result = await getFirebaseStorageImageUrl(`${this.userId}/${imageName}`);
+ logger.debug('[DALL-E] result: ' + this.result);
+ } catch (error) {
+ logger.error('Error while saving the image to Firebase Storage:', error);
+ this.result = `Failed to save the image to Firebase Storage. ${error.message}`;
+ }
+ } else {
+ try {
+ await saveImageFromUrl(theImageUrl, this.outputPath, imageName);
+ this.result = this.getMarkdownImageUrl(imageName);
+ } catch (error) {
+ logger.error('Error while saving the image locally:', error);
+ this.result = `Failed to save the image locally. ${error.message}`;
+ }
}
-
return this.result;
}
}
diff --git a/api/app/clients/tools/structured/DALLE3.js b/api/app/clients/tools/structured/DALLE3.js
index dc5750a6892a..17d0368f395b 100644
--- a/api/app/clients/tools/structured/DALLE3.js
+++ b/api/app/clients/tools/structured/DALLE3.js
@@ -4,10 +4,17 @@ const fs = require('fs');
const path = require('path');
const { z } = require('zod');
const OpenAI = require('openai');
+const { v4: uuidv4 } = require('uuid');
const { Tool } = require('langchain/tools');
const { HttpsProxyAgent } = require('https-proxy-agent');
-const saveImageFromUrl = require('../saveImageFromUrl');
+const {
+ saveImageToFirebaseStorage,
+ getFirebaseStorageImageUrl,
+ getFirebaseStorage,
+} = require('~/server/services/Files/Firebase');
+const { getImageBasename } = require('~/server/services/Files/images');
const extractBaseURL = require('~/utils/extractBaseURL');
+const saveImageFromUrl = require('../saveImageFromUrl');
const { logger } = require('~/config');
const { DALLE3_SYSTEM_PROMPT, DALLE_REVERSE_PROXY, PROXY } = process.env;
@@ -15,6 +22,7 @@ class DALLE3 extends Tool {
constructor(fields = {}) {
super();
+ this.userId = fields.userId;
let apiKey = fields.DALLE_API_KEY || this.getApiKey();
const config = { apiKey };
if (DALLE_REVERSE_PROXY) {
@@ -108,12 +116,12 @@ class DALLE3 extends Tool {
n: 1,
});
} catch (error) {
- return `Something went wrong when trying to generate the image. The DALL-E API may unavailable:
+ return `Something went wrong when trying to generate the image. The DALL-E API may be unavailable:
Error Message: ${error.message}`;
}
if (!resp) {
- return 'Something went wrong when trying to generate the image. The DALL-E API may unavailable';
+ return 'Something went wrong when trying to generate the image. The DALL-E API may be unavailable';
}
const theImageUrl = resp.data[0].url;
@@ -122,12 +130,11 @@ Error Message: ${error.message}`;
return 'No image URL returned from OpenAI API. There may be a problem with the API or your configuration.';
}
- const regex = /img-[\w\d]+.png/;
- const match = theImageUrl.match(regex);
- let imageName = '1.png';
+ const imageBasename = getImageBasename(theImageUrl);
+ let imageName = `image_${uuidv4()}.png`;
- if (match) {
- imageName = match[0];
+ if (imageBasename) {
+ imageName = imageBasename;
logger.debug('[DALL-E-3]', { imageName }); // Output: img-lgCf7ppcbhqQrz6a5ear6FOb.png
} else {
logger.debug('[DALL-E-3] No image name found in the string.', {
@@ -146,6 +153,7 @@ Error Message: ${error.message}`;
'client',
'public',
'images',
+ this.userId,
);
const appRoot = path.resolve(__dirname, '..', '..', '..', '..', '..', 'client');
this.relativeImageUrl = path.relative(appRoot, this.outputPath);
@@ -154,13 +162,24 @@ Error Message: ${error.message}`;
if (!fs.existsSync(this.outputPath)) {
fs.mkdirSync(this.outputPath, { recursive: true });
}
-
- try {
- await saveImageFromUrl(theImageUrl, this.outputPath, imageName);
- this.result = this.getMarkdownImageUrl(imageName);
- } catch (error) {
- logger.error('Error while saving the image:', error);
- this.result = theImageUrl;
+ const storage = getFirebaseStorage();
+ if (storage) {
+ try {
+ await saveImageToFirebaseStorage(this.userId, theImageUrl, imageName);
+ this.result = await getFirebaseStorageImageUrl(`${this.userId}/${imageName}`);
+ logger.debug('[DALL-E-3] result: ' + this.result);
+ } catch (error) {
+ logger.error('Error while saving the image to Firebase Storage:', error);
+ this.result = `Failed to save the image to Firebase Storage. ${error.message}`;
+ }
+ } else {
+ try {
+ await saveImageFromUrl(theImageUrl, this.outputPath, imageName);
+ this.result = this.getMarkdownImageUrl(imageName);
+ } catch (error) {
+ logger.error('Error while saving the image locally:', error);
+ this.result = `Failed to save the image locally. ${error.message}`;
+ }
}
return this.result;
diff --git a/api/app/clients/tools/structured/specs/DALLE3.spec.js b/api/app/clients/tools/structured/specs/DALLE3.spec.js
index c61e1d351302..34fa3ebf00a3 100644
--- a/api/app/clients/tools/structured/specs/DALLE3.spec.js
+++ b/api/app/clients/tools/structured/specs/DALLE3.spec.js
@@ -2,11 +2,40 @@ const fs = require('fs');
const path = require('path');
const OpenAI = require('openai');
const DALLE3 = require('../DALLE3');
+const {
+ getFirebaseStorage,
+ saveImageToFirebaseStorage,
+} = require('~/server/services/Files/Firebase');
const saveImageFromUrl = require('../../saveImageFromUrl');
const { logger } = require('~/config');
jest.mock('openai');
+jest.mock('~/server/services/Files/Firebase', () => ({
+ getFirebaseStorage: jest.fn(),
+ saveImageToFirebaseStorage: jest.fn(),
+ getFirebaseStorageImageUrl: jest.fn(),
+}));
+
+jest.mock('~/server/services/Files/images', () => ({
+ getImageBasename: jest.fn().mockImplementation((url) => {
+ // Split the URL by '/'
+ const parts = url.split('/');
+
+ // Get the last part of the URL
+ const lastPart = parts.pop();
+
+ // Check if the last part of the URL matches the image extension regex
+ const imageExtensionRegex = /\.(jpg|jpeg|png|gif|bmp|tiff|svg)$/i;
+ if (imageExtensionRegex.test(lastPart)) {
+ return lastPart;
+ }
+
+ // If the regex test fails, return an empty string
+ return '';
+ }),
+}));
+
const generate = jest.fn();
OpenAI.mockImplementation(() => ({
images: {
@@ -187,7 +216,48 @@ describe('DALLE3', () => {
generate.mockResolvedValue(mockResponse);
saveImageFromUrl.mockRejectedValue(error);
const result = await dalle._call(mockData);
- expect(logger.error).toHaveBeenCalledWith('Error while saving the image:', error);
- expect(result).toBe(mockResponse.data[0].url);
+ expect(logger.error).toHaveBeenCalledWith('Error while saving the image locally:', error);
+ expect(result).toBe('Failed to save the image locally. Error while saving the image');
+ });
+
+ it('should save image to Firebase Storage if Firebase is initialized', async () => {
+ const mockData = {
+ prompt: 'A test prompt',
+ };
+ const mockImageUrl = 'http://example.com/img-test.png';
+ const mockResponse = { data: [{ url: mockImageUrl }] };
+ generate.mockResolvedValue(mockResponse);
+ getFirebaseStorage.mockReturnValue({}); // Simulate Firebase being initialized
+
+ await dalle._call(mockData);
+
+ expect(getFirebaseStorage).toHaveBeenCalled();
+ expect(saveImageToFirebaseStorage).toHaveBeenCalledWith(
+ undefined,
+ mockImageUrl,
+ expect.any(String),
+ );
+ });
+
+ it('should handle error when saving image to Firebase Storage fails', async () => {
+ const mockData = {
+ prompt: 'A test prompt',
+ };
+ const mockImageUrl = 'http://example.com/img-test.png';
+ const mockResponse = { data: [{ url: mockImageUrl }] };
+ const error = new Error('Error while saving to Firebase');
+ generate.mockResolvedValue(mockResponse);
+ getFirebaseStorage.mockReturnValue({}); // Simulate Firebase being initialized
+ saveImageToFirebaseStorage.mockRejectedValue(error);
+
+ const result = await dalle._call(mockData);
+
+ expect(logger.error).toHaveBeenCalledWith(
+ 'Error while saving the image to Firebase Storage:',
+ error,
+ );
+ expect(result).toBe(
+ 'Failed to save the image to Firebase Storage. Error while saving to Firebase',
+ );
});
});
diff --git a/api/app/clients/tools/util/handleTools.js b/api/app/clients/tools/util/handleTools.js
index 3afe2776729e..352dd5dec740 100644
--- a/api/app/clients/tools/util/handleTools.js
+++ b/api/app/clients/tools/util/handleTools.js
@@ -67,19 +67,19 @@ const validateTools = async (user, tools = []) => {
}
};
-const loadToolWithAuth = async (user, authFields, ToolConstructor, options = {}) => {
+const loadToolWithAuth = async (userId, authFields, ToolConstructor, options = {}) => {
return async function () {
let authValues = {};
for (const authField of authFields) {
let authValue = process.env[authField];
if (!authValue) {
- authValue = await getUserPluginAuthValue(user, authField);
+ authValue = await getUserPluginAuthValue(userId, authField);
}
authValues[authField] = authValue;
}
- return new ToolConstructor({ ...options, ...authValues });
+ return new ToolConstructor({ ...options, ...authValues, userId });
};
};
diff --git a/api/package.json b/api/package.json
index 684d13978947..fe5731cbd2fb 100644
--- a/api/package.json
+++ b/api/package.json
@@ -44,6 +44,7 @@
"express-mongo-sanitize": "^2.2.0",
"express-rate-limit": "^6.9.0",
"express-session": "^1.17.3",
+ "firebase": "^10.6.0",
"googleapis": "^126.0.1",
"handlebars": "^4.7.7",
"html": "^1.0.0",
diff --git a/api/server/index.js b/api/server/index.js
index 230f8e79d95c..698620c56f3a 100644
--- a/api/server/index.js
+++ b/api/server/index.js
@@ -4,6 +4,7 @@ const cors = require('cors');
const express = require('express');
const passport = require('passport');
const mongoSanitize = require('express-mongo-sanitize');
+const { initializeFirebase } = require('~/server/services/Files/Firebase/initialize');
const errorController = require('./controllers/ErrorController');
const configureSocialLogins = require('./socialLogins');
const { connectDb, indexSync } = require('~/lib/db');
@@ -23,6 +24,7 @@ const { jwtLogin, passportLogin } = require('~/strategies');
const startServer = async () => {
await connectDb();
logger.info('Connected to MongoDB');
+ initializeFirebase();
await indexSync();
const app = express();
diff --git a/api/server/routes/files/avatar.js b/api/server/routes/files/avatar.js
new file mode 100644
index 000000000000..a7bb07c0f95f
--- /dev/null
+++ b/api/server/routes/files/avatar.js
@@ -0,0 +1,34 @@
+const express = require('express');
+const multer = require('multer');
+
+const uploadAvatar = require('~/server/services/Files/images/avatar/uploadAvatar');
+const { requireJwtAuth } = require('~/server/middleware/');
+const User = require('~/models/User');
+
+const upload = multer();
+const router = express.Router();
+
+router.post('/', requireJwtAuth, upload.single('input'), async (req, res) => {
+ try {
+ const userId = req.user.id;
+ const { manual } = req.body;
+ const input = req.file.buffer;
+ if (!userId) {
+ throw new Error('User ID is undefined');
+ }
+
+ // TODO: do not use Model directly, instead use a service method that uses the model
+ const user = await User.findById(userId).lean();
+
+ if (!user) {
+ throw new Error('User not found');
+ }
+ const url = await uploadAvatar(userId, input, manual);
+
+ res.json({ url });
+ } catch (error) {
+ res.status(500).json({ message: 'An error occurred while uploading the profile picture' });
+ }
+});
+
+module.exports = router;
diff --git a/api/server/routes/files/index.js b/api/server/routes/files/index.js
index 34c7dc62e3ad..74b200c80665 100644
--- a/api/server/routes/files/index.js
+++ b/api/server/routes/files/index.js
@@ -18,5 +18,6 @@ router.use(uaParser);
router.use('/', files);
router.use('/images', images);
+router.use('/images/avatar', require('./avatar'));
module.exports = router;
diff --git a/api/server/services/Files/Firebase/images.js b/api/server/services/Files/Firebase/images.js
new file mode 100644
index 000000000000..e04902c02fe0
--- /dev/null
+++ b/api/server/services/Files/Firebase/images.js
@@ -0,0 +1,45 @@
+const fetch = require('node-fetch');
+const { ref, uploadBytes, getDownloadURL } = require('firebase/storage');
+const { getFirebaseStorage } = require('./initialize');
+
+async function saveImageToFirebaseStorage(userId, imageUrl, imageName) {
+ const storage = getFirebaseStorage();
+ if (!storage) {
+ console.error('Firebase is not initialized. Cannot save image to Firebase Storage.');
+ return null;
+ }
+
+ const storageRef = ref(storage, `images/${userId.toString()}/${imageName}`);
+
+ try {
+ // Upload image to Firebase Storage using the image URL
+ await uploadBytes(storageRef, await fetch(imageUrl).then((response) => response.buffer()));
+ return imageName;
+ } catch (error) {
+ console.error('Error uploading image to Firebase Storage:', error.message);
+ return null;
+ }
+}
+
+async function getFirebaseStorageImageUrl(imageName) {
+ const storage = getFirebaseStorage();
+ if (!storage) {
+ console.error('Firebase is not initialized. Cannot get image URL from Firebase Storage.');
+ return null;
+ }
+
+ const storageRef = ref(storage, `images/${imageName}`);
+
+ try {
+ // Get the download URL for the image from Firebase Storage
+ return `![generated image](${await getDownloadURL(storageRef)})`;
+ } catch (error) {
+ console.error('Error fetching image URL from Firebase Storage:', error.message);
+ return null;
+ }
+}
+
+module.exports = {
+ saveImageToFirebaseStorage,
+ getFirebaseStorageImageUrl,
+};
diff --git a/api/server/services/Files/Firebase/index.js b/api/server/services/Files/Firebase/index.js
new file mode 100644
index 000000000000..905bf660d4fe
--- /dev/null
+++ b/api/server/services/Files/Firebase/index.js
@@ -0,0 +1,7 @@
+const images = require('./images');
+const initialize = require('./initialize');
+
+module.exports = {
+ ...images,
+ ...initialize,
+};
diff --git a/api/server/services/Files/Firebase/initialize.js b/api/server/services/Files/Firebase/initialize.js
new file mode 100644
index 000000000000..5dc1f9379157
--- /dev/null
+++ b/api/server/services/Files/Firebase/initialize.js
@@ -0,0 +1,42 @@
+const firebase = require('firebase/app');
+const { getStorage } = require('firebase/storage');
+const { logger } = require('~/config');
+
+let i = 0;
+let firebaseApp = null;
+
+const initializeFirebase = () => {
+ // Return existing instance if already initialized
+ if (firebaseApp) {
+ return firebaseApp;
+ }
+
+ const firebaseConfig = {
+ apiKey: process.env.FIREBASE_API_KEY,
+ authDomain: process.env.FIREBASE_AUTH_DOMAIN,
+ projectId: process.env.FIREBASE_PROJECT_ID,
+ storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
+ messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
+ appId: process.env.FIREBASE_APP_ID,
+ };
+
+ if (Object.values(firebaseConfig).some((value) => !value)) {
+ i === 0 &&
+ logger.info(
+ '[Optional] Firebase configuration missing or incomplete. Firebase will not be initialized.',
+ );
+ i++;
+ return null;
+ }
+
+ firebaseApp = firebase.initializeApp(firebaseConfig);
+ logger.info('Firebase initialized');
+ return firebaseApp;
+};
+
+const getFirebaseStorage = () => {
+ const app = initializeFirebase();
+ return app ? getStorage(app) : null;
+};
+
+module.exports = { initializeFirebase, getFirebaseStorage };
diff --git a/api/server/services/Files/images/avatar/firebaseStrategy.js b/api/server/services/Files/images/avatar/firebaseStrategy.js
new file mode 100644
index 000000000000..9c000b43ecc4
--- /dev/null
+++ b/api/server/services/Files/images/avatar/firebaseStrategy.js
@@ -0,0 +1,29 @@
+const { ref, uploadBytes, getDownloadURL } = require('firebase/storage');
+const { getFirebaseStorage } = require('~/server/services/Files/Firebase/initialize');
+const { logger } = require('~/config');
+
+async function firebaseStrategy(userId, webPBuffer, oldUser, manual) {
+ try {
+ const storage = getFirebaseStorage();
+ if (!storage) {
+ throw new Error('Firebase is not initialized.');
+ }
+ const avatarRef = ref(storage, `images/${userId.toString()}/avatar`);
+
+ await uploadBytes(avatarRef, webPBuffer);
+ const urlFirebase = await getDownloadURL(avatarRef);
+ const isManual = manual === 'true';
+
+ const url = `${urlFirebase}?manual=${isManual}`;
+ if (isManual) {
+ oldUser.avatar = url;
+ await oldUser.save();
+ }
+ return url;
+ } catch (error) {
+ logger.error('Error uploading profile picture:', error);
+ throw error;
+ }
+}
+
+module.exports = firebaseStrategy;
diff --git a/api/server/services/Files/images/avatar/localStrategy.js b/api/server/services/Files/images/avatar/localStrategy.js
new file mode 100644
index 000000000000..021beda7d13f
--- /dev/null
+++ b/api/server/services/Files/images/avatar/localStrategy.js
@@ -0,0 +1,32 @@
+const fs = require('fs').promises;
+const path = require('path');
+
+async function localStrategy(userId, webPBuffer, oldUser, manual) {
+ const userDir = path.resolve(
+ __dirname,
+ '..',
+ '..',
+ '..',
+ '..',
+ '..',
+ '..',
+ 'client',
+ 'public',
+ 'images',
+ userId,
+ );
+ let avatarPath = path.join(userDir, 'avatar.png');
+ const urlRoute = `/images/${userId}/avatar.png`;
+ await fs.mkdir(userDir, { recursive: true });
+ await fs.writeFile(avatarPath, webPBuffer);
+ const isManual = manual === 'true';
+ let url = `${urlRoute}?manual=${isManual}×tamp=${new Date().getTime()}`;
+ if (isManual) {
+ oldUser.avatar = url;
+ await oldUser.save();
+ }
+
+ return url;
+}
+
+module.exports = localStrategy;
diff --git a/api/server/services/Files/images/avatar/uploadAvatar.js b/api/server/services/Files/images/avatar/uploadAvatar.js
new file mode 100644
index 000000000000..0726df9a4dde
--- /dev/null
+++ b/api/server/services/Files/images/avatar/uploadAvatar.js
@@ -0,0 +1,63 @@
+const sharp = require('sharp');
+const fetch = require('node-fetch');
+const fs = require('fs').promises;
+const User = require('~/models/User');
+const { getFirebaseStorage } = require('~/server/services/Files/Firebase/initialize');
+const firebaseStrategy = require('./firebaseStrategy');
+const localStrategy = require('./localStrategy');
+const { logger } = require('~/config');
+
+async function convertToWebP(inputBuffer) {
+ return sharp(inputBuffer).resize({ width: 150 }).toFormat('webp').toBuffer();
+}
+
+async function uploadAvatar(userId, input, manual) {
+ try {
+ if (userId === undefined) {
+ throw new Error('User ID is undefined');
+ }
+ const _id = userId;
+ // TODO: remove direct use of Model, `User`
+ const oldUser = await User.findOne({ _id });
+ let imageBuffer;
+ if (typeof input === 'string') {
+ const response = await fetch(input);
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch image from URL. Status: ${response.status}`);
+ }
+ imageBuffer = await response.buffer();
+ } else if (input instanceof Buffer) {
+ imageBuffer = input;
+ } else if (typeof input === 'object' && input instanceof File) {
+ const fileContent = await fs.readFile(input.path);
+ imageBuffer = Buffer.from(fileContent);
+ } else {
+ throw new Error('Invalid input type. Expected URL, Buffer, or File.');
+ }
+ const { width, height } = await sharp(imageBuffer).metadata();
+ const minSize = Math.min(width, height);
+ const squaredBuffer = await sharp(imageBuffer)
+ .extract({
+ left: Math.floor((width - minSize) / 2),
+ top: Math.floor((height - minSize) / 2),
+ width: minSize,
+ height: minSize,
+ })
+ .toBuffer();
+ const webPBuffer = await convertToWebP(squaredBuffer);
+ const storage = getFirebaseStorage();
+ if (storage) {
+ const url = await firebaseStrategy(userId, webPBuffer, oldUser, manual);
+ return url;
+ }
+
+ const url = await localStrategy(userId, webPBuffer, oldUser, manual);
+ return url;
+ } catch (error) {
+ logger.error('Error uploading the avatar:', error);
+ throw error;
+ }
+}
+
+module.exports = uploadAvatar;
diff --git a/api/server/services/Files/images/index.js b/api/server/services/Files/images/index.js
index d5b818e937d8..fa49eb953567 100644
--- a/api/server/services/Files/images/index.js
+++ b/api/server/services/Files/images/index.js
@@ -1,11 +1,15 @@
const convert = require('./convert');
const encode = require('./encode');
+const parse = require('./parse');
const resize = require('./resize');
const validate = require('./validate');
+const uploadAvatar = require('./avatar/uploadAvatar');
module.exports = {
...convert,
...encode,
+ ...parse,
...resize,
...validate,
+ uploadAvatar,
};
diff --git a/api/server/services/Files/images/parse.js b/api/server/services/Files/images/parse.js
new file mode 100644
index 000000000000..5a1113c97e41
--- /dev/null
+++ b/api/server/services/Files/images/parse.js
@@ -0,0 +1,27 @@
+const URL = require('url').URL;
+const path = require('path');
+
+const imageExtensionRegex = /\.(jpg|jpeg|png|gif|bmp|tiff|svg)$/i;
+
+/**
+ * Extracts the image basename from a given URL.
+ *
+ * @param {string} urlString - The URL string from which the image basename is to be extracted.
+ * @returns {string} The basename of the image file from the URL.
+ * Returns an empty string if the URL does not contain a valid image basename.
+ */
+function getImageBasename(urlString) {
+ try {
+ const url = new URL(urlString);
+ const basename = path.basename(url.pathname);
+
+ return imageExtensionRegex.test(basename) ? basename : '';
+ } catch (error) {
+ // If URL parsing fails, return an empty string
+ return '';
+ }
+}
+
+module.exports = {
+ getImageBasename,
+};
diff --git a/api/strategies/discordStrategy.js b/api/strategies/discordStrategy.js
index c6fdde6d8c36..994554200cd4 100644
--- a/api/strategies/discordStrategy.js
+++ b/api/strategies/discordStrategy.js
@@ -1,51 +1,72 @@
const { Strategy: DiscordStrategy } = require('passport-discord');
const { logger } = require('~/config');
const User = require('~/models/User');
+const { useFirebase, uploadAvatar } = require('~/server/services/Files/images');
const discordLogin = async (accessToken, refreshToken, profile, cb) => {
try {
const email = profile.email;
const discordId = profile.id;
- const oldUser = await User.findOne({
- email,
- });
+ const oldUser = await User.findOne({ email });
const ALLOW_SOCIAL_REGISTRATION =
process.env.ALLOW_SOCIAL_REGISTRATION?.toLowerCase() === 'true';
- let avatarURL;
+ let avatarUrl;
+
if (profile.avatar) {
const format = profile.avatar.startsWith('a_') ? 'gif' : 'png';
- avatarURL = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;
+ avatarUrl = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;
} else {
const defaultAvatarNum = Number(profile.discriminator) % 5;
- avatarURL = `https://cdn.discordapp.com/embed/avatars/${defaultAvatarNum}.png`;
+ avatarUrl = `https://cdn.discordapp.com/embed/avatars/${defaultAvatarNum}.png`;
}
if (oldUser) {
- oldUser.avatar = avatarURL;
- await oldUser.save();
+ await handleExistingUser(oldUser, avatarUrl, useFirebase);
return cb(null, oldUser);
- } else if (ALLOW_SOCIAL_REGISTRATION) {
- const newUser = await new User({
- provider: 'discord',
- discordId,
- username: profile.username,
- email,
- name: profile.global_name,
- avatar: avatarURL,
- }).save();
+ }
+ if (ALLOW_SOCIAL_REGISTRATION) {
+ const newUser = await createNewUser(profile, discordId, email, avatarUrl, useFirebase);
return cb(null, newUser);
}
-
- return cb(null, false, {
- message: 'User not found.',
- });
} catch (err) {
logger.error('[discordLogin]', err);
return cb(err);
}
};
+const handleExistingUser = async (oldUser, avatarUrl, useFirebase) => {
+ if (!useFirebase && !oldUser.avatar.includes('?manual=true')) {
+ oldUser.avatar = avatarUrl;
+ await oldUser.save();
+ } else if (useFirebase && !oldUser.avatar.includes('?manual=true')) {
+ const userId = oldUser._id;
+ const newavatarUrl = await uploadAvatar(userId, avatarUrl);
+ oldUser.avatar = newavatarUrl;
+ await oldUser.save();
+ }
+};
+
+const createNewUser = async (profile, discordId, email, avatarUrl, useFirebase) => {
+ const newUser = await new User({
+ provider: 'discord',
+ discordId,
+ username: profile.username,
+ email,
+ name: profile.global_name,
+ avatar: avatarUrl,
+ }).save();
+
+ if (useFirebase) {
+ const userId = newUser._id;
+ const newavatarUrl = await uploadAvatar(userId, avatarUrl);
+ newUser.avatar = newavatarUrl;
+ await newUser.save();
+ }
+
+ return newUser;
+};
+
module.exports = () =>
new DiscordStrategy(
{
diff --git a/api/strategies/facebookStrategy.js b/api/strategies/facebookStrategy.js
index bb175a099cc2..b8915b2cc4bf 100644
--- a/api/strategies/facebookStrategy.js
+++ b/api/strategies/facebookStrategy.js
@@ -1,43 +1,64 @@
const FacebookStrategy = require('passport-facebook').Strategy;
const { logger } = require('~/config');
const User = require('~/models/User');
+const { useFirebase, uploadAvatar } = require('~/server/services/Files/images');
const facebookLogin = async (accessToken, refreshToken, profile, cb) => {
try {
const email = profile.emails[0]?.value;
const facebookId = profile.id;
- const oldUser = await User.findOne({
- email,
- });
+ const oldUser = await User.findOne({ email });
const ALLOW_SOCIAL_REGISTRATION =
process.env.ALLOW_SOCIAL_REGISTRATION?.toLowerCase() === 'true';
+ const avatarUrl = profile.photos[0]?.value;
if (oldUser) {
- oldUser.avatar = profile.photo;
- await oldUser.save();
+ await handleExistingUser(oldUser, avatarUrl, useFirebase);
return cb(null, oldUser);
- } else if (ALLOW_SOCIAL_REGISTRATION) {
- const newUser = await new User({
- provider: 'facebook',
- facebookId,
- username: profile.displayName,
- email,
- name: profile.name?.givenName + ' ' + profile.name?.familyName,
- avatar: profile.photos[0]?.value,
- }).save();
+ }
+ if (ALLOW_SOCIAL_REGISTRATION) {
+ const newUser = await createNewUser(profile, facebookId, email, avatarUrl, useFirebase);
return cb(null, newUser);
}
-
- return cb(null, false, {
- message: 'User not found.',
- });
} catch (err) {
logger.error('[facebookLogin]', err);
return cb(err);
}
};
+const handleExistingUser = async (oldUser, avatarUrl, useFirebase) => {
+ if (!useFirebase && !oldUser.avatar.includes('?manual=true')) {
+ oldUser.avatar = avatarUrl;
+ await oldUser.save();
+ } else if (useFirebase && !oldUser.avatar.includes('?manual=true')) {
+ const userId = oldUser._id;
+ const newavatarUrl = await uploadAvatar(userId, avatarUrl);
+ oldUser.avatar = newavatarUrl;
+ await oldUser.save();
+ }
+};
+
+const createNewUser = async (profile, facebookId, email, avatarUrl, useFirebase) => {
+ const newUser = await new User({
+ provider: 'facebook',
+ facebookId,
+ username: profile.displayName,
+ email,
+ name: profile.name?.givenName + ' ' + profile.name?.familyName,
+ avatar: avatarUrl,
+ }).save();
+
+ if (useFirebase) {
+ const userId = newUser._id;
+ const newavatarUrl = await uploadAvatar(userId, avatarUrl);
+ newUser.avatar = newavatarUrl;
+ await newUser.save();
+ }
+
+ return newUser;
+};
+
module.exports = () =>
new FacebookStrategy(
{
diff --git a/api/strategies/githubStrategy.js b/api/strategies/githubStrategy.js
index 3962c58e50e7..c8480d50c135 100644
--- a/api/strategies/githubStrategy.js
+++ b/api/strategies/githubStrategy.js
@@ -1,6 +1,7 @@
const { Strategy: GitHubStrategy } = require('passport-github2');
const { logger } = require('~/config');
const User = require('~/models/User');
+const { useFirebase, uploadAvatar } = require('~/server/services/Files/images');
const githubLogin = async (accessToken, refreshToken, profile, cb) => {
try {
@@ -9,32 +10,56 @@ const githubLogin = async (accessToken, refreshToken, profile, cb) => {
const oldUser = await User.findOne({ email });
const ALLOW_SOCIAL_REGISTRATION =
process.env.ALLOW_SOCIAL_REGISTRATION?.toLowerCase() === 'true';
+ const avatarUrl = profile.photos[0].value;
if (oldUser) {
- oldUser.avatar = profile.photos[0].value;
- await oldUser.save();
+ await handleExistingUser(oldUser, avatarUrl, useFirebase);
return cb(null, oldUser);
- } else if (ALLOW_SOCIAL_REGISTRATION) {
- const newUser = await new User({
- provider: 'github',
- githubId,
- username: profile.username,
- email,
- emailVerified: profile.emails[0].verified,
- name: profile.displayName,
- avatar: profile.photos[0].value,
- }).save();
+ }
+ if (ALLOW_SOCIAL_REGISTRATION) {
+ const newUser = await createNewUser(profile, githubId, email, avatarUrl, useFirebase);
return cb(null, newUser);
}
-
- return cb(null, false, { message: 'User not found.' });
} catch (err) {
logger.error('[githubLogin]', err);
return cb(err);
}
};
+const handleExistingUser = async (oldUser, avatarUrl, useFirebase) => {
+ if (!useFirebase && !oldUser.avatar.includes('?manual=true')) {
+ oldUser.avatar = avatarUrl;
+ await oldUser.save();
+ } else if (useFirebase && !oldUser.avatar.includes('?manual=true')) {
+ const userId = oldUser._id;
+ const avatarURL = await uploadAvatar(userId, avatarUrl);
+ oldUser.avatar = avatarURL;
+ await oldUser.save();
+ }
+};
+
+const createNewUser = async (profile, githubId, email, avatarUrl, useFirebase) => {
+ const newUser = await new User({
+ provider: 'github',
+ githubId,
+ username: profile.username,
+ email,
+ emailVerified: profile.emails[0].verified,
+ name: profile.displayName,
+ avatar: avatarUrl,
+ }).save();
+
+ if (useFirebase) {
+ const userId = newUser._id;
+ const avatarURL = await uploadAvatar(userId, avatarUrl);
+ newUser.avatar = avatarURL;
+ await newUser.save();
+ }
+
+ return newUser;
+};
+
module.exports = () =>
new GitHubStrategy(
{
diff --git a/api/strategies/googleStrategy.js b/api/strategies/googleStrategy.js
index e65c5403f4bb..d013cc8e8fdb 100644
--- a/api/strategies/googleStrategy.js
+++ b/api/strategies/googleStrategy.js
@@ -1,6 +1,7 @@
const { Strategy: GoogleStrategy } = require('passport-google-oauth20');
const { logger } = require('~/config');
const User = require('~/models/User');
+const { useFirebase, uploadAvatar } = require('~/server/services/Files/images');
const googleLogin = async (accessToken, refreshToken, profile, cb) => {
try {
@@ -9,32 +10,56 @@ const googleLogin = async (accessToken, refreshToken, profile, cb) => {
const oldUser = await User.findOne({ email });
const ALLOW_SOCIAL_REGISTRATION =
process.env.ALLOW_SOCIAL_REGISTRATION?.toLowerCase() === 'true';
+ const avatarUrl = profile.photos[0].value;
if (oldUser) {
- oldUser.avatar = profile.photos[0].value;
- await oldUser.save();
+ await handleExistingUser(oldUser, avatarUrl, useFirebase);
return cb(null, oldUser);
- } else if (ALLOW_SOCIAL_REGISTRATION) {
- const newUser = await new User({
- provider: 'google',
- googleId,
- username: profile.name.givenName,
- email,
- emailVerified: profile.emails[0].verified,
- name: `${profile.name.givenName} ${profile.name.familyName}`,
- avatar: profile.photos[0].value,
- }).save();
+ }
+ if (ALLOW_SOCIAL_REGISTRATION) {
+ const newUser = await createNewUser(profile, googleId, email, avatarUrl, useFirebase);
return cb(null, newUser);
}
-
- return cb(null, false, { message: 'User not found.' });
} catch (err) {
logger.error('[googleLogin]', err);
return cb(err);
}
};
+const handleExistingUser = async (oldUser, avatarUrl, useFirebase) => {
+ if ((!useFirebase && !oldUser.avatar.includes('?manual=true')) || oldUser.avatar === null) {
+ oldUser.avatar = avatarUrl;
+ await oldUser.save();
+ } else if (useFirebase && !oldUser.avatar.includes('?manual=true')) {
+ const userId = oldUser._id;
+ const avatarURL = await uploadAvatar(userId, avatarUrl);
+ oldUser.avatar = avatarURL;
+ await oldUser.save();
+ }
+};
+
+const createNewUser = async (profile, googleId, email, avatarUrl, useFirebase) => {
+ const newUser = await new User({
+ provider: 'google',
+ googleId,
+ username: profile.name.givenName,
+ email,
+ emailVerified: profile.emails[0].verified,
+ name: `${profile.name.givenName} ${profile.name.familyName}`,
+ avatar: avatarUrl,
+ }).save();
+
+ if (useFirebase) {
+ const userId = newUser._id;
+ const avatarURL = await uploadAvatar(userId, avatarUrl);
+ newUser.avatar = avatarURL;
+ await newUser.save();
+ }
+
+ return newUser;
+};
+
module.exports = () =>
new GoogleStrategy(
{
diff --git a/client/src/App.jsx b/client/src/App.jsx
index 72d07b1c96a4..10c9ab9b509b 100644
--- a/client/src/App.jsx
+++ b/client/src/App.jsx
@@ -34,7 +34,7 @@ const App = () => {
-
+
diff --git a/client/src/common/types.ts b/client/src/common/types.ts
index 807e2dc9424f..2daf2d8ba0f2 100644
--- a/client/src/common/types.ts
+++ b/client/src/common/types.ts
@@ -27,6 +27,7 @@ export type TShowToast = {
severity?: NotificationSeverity;
showIcon?: boolean;
duration?: number;
+ status?: 'error' | 'success' | 'warning' | 'info';
};
export type TBaseSettingsProps = {
diff --git a/client/src/components/Chat/ChatView.tsx b/client/src/components/Chat/ChatView.tsx
index 5ce309513956..d582f4b3e9d8 100644
--- a/client/src/components/Chat/ChatView.tsx
+++ b/client/src/components/Chat/ChatView.tsx
@@ -6,10 +6,10 @@ import { useChatHelpers, useSSE } from '~/hooks';
// import GenerationButtons from './Input/GenerationButtons';
import MessagesView from './Messages/MessagesView';
// import OptionsBar from './Input/OptionsBar';
+import { Spinner } from '~/components/svg';
import { ChatContext } from '~/Providers';
import Presentation from './Presentation';
import ChatForm from './Input/ChatForm';
-import { Spinner } from '~/components';
import { buildTree } from '~/utils';
import Landing from './Landing';
import Header from './Header';
diff --git a/client/src/components/Nav/Nav.tsx b/client/src/components/Nav/Nav.tsx
index 552fd1d52576..86a3e3359718 100644
--- a/client/src/components/Nav/Nav.tsx
+++ b/client/src/components/Nav/Nav.tsx
@@ -11,7 +11,7 @@ import {
} from '~/hooks';
import { TooltipProvider, Tooltip } from '~/components/ui';
import { Conversations, Pages } from '../Conversations';
-import { Spinner } from '~/components';
+import { Spinner } from '~/components/svg';
import SearchBar from './SearchBar';
import NavToggle from './NavToggle';
import NavLinks from './NavLinks';
diff --git a/client/src/components/Nav/NavLinks.tsx b/client/src/components/Nav/NavLinks.tsx
index ad1b9610cbb8..2f5c0769bcb6 100644
--- a/client/src/components/Nav/NavLinks.tsx
+++ b/client/src/components/Nav/NavLinks.tsx
@@ -119,7 +119,7 @@ function NavLinks() {
}
+ svg={() => }
text={localize('com_nav_settings')}
clickHandler={() => setShowSettings(true)}
/>
diff --git a/client/src/components/Nav/Settings.tsx b/client/src/components/Nav/Settings.tsx
index cce7ec27c20d..da3fcefa7cf8 100644
--- a/client/src/components/Nav/Settings.tsx
+++ b/client/src/components/Nav/Settings.tsx
@@ -1,9 +1,9 @@
import * as Tabs from '@radix-ui/react-tabs';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '~/components/ui';
-import { GearIcon, DataIcon } from '~/components/svg';
+import { GearIcon, DataIcon, UserIcon } from '~/components/svg';
import { useMediaQuery, useLocalize } from '~/hooks';
import type { TDialogProps } from '~/common';
-import { General, Data } from './SettingsTabs';
+import { General, Data, Account } from './SettingsTabs';
import { cn } from '~/utils';
export default function Settings({ open, onOpenChange }: TDialogProps) {
@@ -39,7 +39,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
>
{localize('com_nav_setting_data')}
+
+
+ {localize('com_nav_setting_account')}
+
+
diff --git a/client/src/components/Nav/SettingsTabs/Account/Account.tsx b/client/src/components/Nav/SettingsTabs/Account/Account.tsx
new file mode 100644
index 000000000000..a7651ddca603
--- /dev/null
+++ b/client/src/components/Nav/SettingsTabs/Account/Account.tsx
@@ -0,0 +1,18 @@
+import * as Tabs from '@radix-ui/react-tabs';
+import Avatar from './Avatar';
+import React from 'react';
+
+function Account() {
+ return (
+
+