diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 5951ed694ea..41ca0502b46 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -4,7 +4,7 @@ Thank you to all the contributors who have helped make this project possible! We
## Contributing Guidelines
-If the feature you would like to contribute has not already received prior approval from the project maintainers (i.e., the feature is currently on the [roadmap](https://github.com/users/danny-avila/projects/2)), please submit a request in the [Feature Requests & Suggestions category](https://github.com/danny-avila/LibreChat/discussions/new?category=feature-requests-suggestions) of the discussions board before beginning work on it. The requests should include specific implementation details, including areas of the application that will be affected by the change (including designs if applicable), and any other relevant information that might be required for a speedy review. However, proposals are not required for small changes, bug fixes, or documentation improvements. Small changes and bug fixes should be tied to an [issue](https://github.com/danny-avila/LibreChat/issues) and included in the corresponding pull request for tracking purposes.
+If the feature you would like to contribute has not already received prior approval from the project maintainers (i.e., the feature is currently on the [roadmap](https://github.com/users/enricai/projects/2)), please submit a request in the [Feature Requests & Suggestions category](https://github.com/enricai/LibreChat/discussions/new?category=feature-requests-suggestions) of the discussions board before beginning work on it. The requests should include specific implementation details, including areas of the application that will be affected by the change (including designs if applicable), and any other relevant information that might be required for a speedy review. However, proposals are not required for small changes, bug fixes, or documentation improvements. Small changes and bug fixes should be tied to an [issue](https://github.com/enricai/LibreChat/issues) and included in the corresponding pull request for tracking purposes.
Please note that a pull request involving a feature that has not been reviewed and approved by the project maintainers may be rejected. We appreciate your understanding and cooperation.
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 37ef799acbd..e0456c0a195 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,6 +1,6 @@
# These are supported funding model platforms
-github: [danny-avila]
+github: [enricai]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml
index 5c88b9f70dc..a4a5aff2e21 100644
--- a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml
+++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml
@@ -50,7 +50,7 @@ body:
id: terms
attributes:
label: Code of Conduct
- description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/danny-avila/LibreChat/blob/main/.github/CODE_OF_CONDUCT.md)
+ description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/enricai/LibreChat/blob/main/.github/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow this project's Code of Conduct
required: true
diff --git a/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml
index d85957fd22e..8339b60b567 100644
--- a/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml
+++ b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml
@@ -43,7 +43,7 @@ body:
id: terms
attributes:
label: Code of Conduct
- description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/danny-avila/LibreChat/blob/main/.github/CODE_OF_CONDUCT.md)
+ description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/enricai/LibreChat/blob/main/.github/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow this project's Code of Conduct
required: true
diff --git a/.github/ISSUE_TEMPLATE/QUESTION.yml b/.github/ISSUE_TEMPLATE/QUESTION.yml
index 0669fd67244..23a19db7509 100644
--- a/.github/ISSUE_TEMPLATE/QUESTION.yml
+++ b/.github/ISSUE_TEMPLATE/QUESTION.yml
@@ -44,7 +44,7 @@ body:
id: terms
attributes:
label: Code of Conduct
- description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/danny-avila/LibreChat/blob/main/.github/CODE_OF_CONDUCT.md)
+ description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/enricai/LibreChat/blob/main/.github/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow this project's Code of Conduct
required: true
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index b01e04e0160..c8afca899c2 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -43,7 +43,7 @@ This security policy applies to the following GitHub repository:
## Contact
-If you have any questions or concerns regarding the security of our project, please join our [Discord community](https://discord.librechat.ai) and report them in the appropriate channel. You can also reach out to us by [opening an issue](https://github.com/danny-avila/LibreChat/issues/new) on GitHub. Please note that the response time may vary depending on the nature and severity of the inquiry.
+If you have any questions or concerns regarding the security of our project, please join our [Discord community](https://discord.librechat.ai) and report them in the appropriate channel. You can also reach out to us by [opening an issue](https://github.com/enricai/LibreChat/issues/new) on GitHub. Please note that the response time may vary depending on the nature and severity of the inquiry.
## Acknowledgments
diff --git a/.github/playwright.yml b/.github/playwright.yml
index 28eca14d581..984eb42c255 100644
--- a/.github/playwright.yml
+++ b/.github/playwright.yml
@@ -13,7 +13,7 @@
# jobs:
# tests_e2e:
# name: Run Playwright tests
-# if: github.event.pull_request.head.repo.full_name == 'danny-avila/LibreChat'
+# if: github.event.pull_request.head.repo.full_name == 'enricai/LibreChat'
# timeout-minutes: 60
# runs-on: ubuntu-latest
# env:
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index cb637787f12..7d4e3bd8d3c 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,7 +1,7 @@
# Pull Request Template
⚠️ Before Submitting a PR, Please Review:
-- Please ensure that you have thoroughly read and understood the [Contributing Docs](https://github.com/danny-avila/LibreChat/blob/main/.github/CONTRIBUTING.md) before submitting your Pull Request.
+- Please ensure that you have thoroughly read and understood the [Contributing Docs](https://github.com/enricai/LibreChat/blob/main/.github/CONTRIBUTING.md) before submitting your Pull Request.
⚠️ Documentation Updates Notice:
- Kindly note that documentation updates are managed in this repository: [librechat.ai](https://github.com/LibreChat-AI/librechat.ai)
diff --git a/.github/workflows/a11y.yml b/.github/workflows/a11y.yml
index a7cfd08169b..075aa7c17ac 100644
--- a/.github/workflows/a11y.yml
+++ b/.github/workflows/a11y.yml
@@ -15,7 +15,7 @@ jobs:
axe-linter:
runs-on: ubuntu-latest
if: >
- (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'danny-avila/LibreChat') ||
+ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'enricai/LibreChat') ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_workflow == 'true')
steps:
diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml
index fc1c02db69f..dd35f38a05b 100644
--- a/.github/workflows/deploy-dev.yml
+++ b/.github/workflows/deploy-dev.yml
@@ -11,7 +11,7 @@ jobs:
deploy:
runs-on: ubuntu-latest
if: |
- github.repository == 'danny-avila/LibreChat' &&
+ github.repository == 'enricai/LibreChat' &&
(github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success')
steps:
- name: Checkout repository
diff --git a/README.md b/README.md
index 317a7a0669d..549bb5d1f1b 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@
-
+
@@ -136,7 +136,7 @@ Click on the thumbnail to open the video☝️
## 📝 Changelog
Keep up with the latest updates by visiting the releases page and notes:
-- [Releases](https://github.com/danny-avila/LibreChat/releases)
+- [Releases](https://github.com/enricai/LibreChat/releases)
- [Changelog](https://www.librechat.ai/changelog)
**⚠️ Please consult the [changelog](https://www.librechat.ai/changelog) for breaking changes before updating.**
@@ -146,13 +146,13 @@ Keep up with the latest updates by visiting the releases page and notes:
## ⭐ Star History
-
-
+
+
-
+
@@ -171,6 +171,6 @@ For new features, components, or extensions, please open an issue and discuss be
## 💖 This project exists in its current state thanks to all the people who contribute
-
-
+
+
diff --git a/api/app/clients/ChatGPTClient.js b/api/app/clients/ChatGPTClient.js
index 6a7ba7b9896..451d88569e3 100644
--- a/api/app/clients/ChatGPTClient.js
+++ b/api/app/clients/ChatGPTClient.js
@@ -272,7 +272,7 @@ class ChatGPTClient extends BaseClient {
if (this.useOpenRouter) {
opts.headers['HTTP-Referer'] = 'https://librechat.ai';
- opts.headers['X-Title'] = 'LibreChat';
+ opts.headers['X-Title'] = 'EnricChat';
}
if (this.options.proxy) {
diff --git a/api/app/clients/OpenAIClient.js b/api/app/clients/OpenAIClient.js
index 15fd20aefe7..3c0c90b8b98 100644
--- a/api/app/clients/OpenAIClient.js
+++ b/api/app/clients/OpenAIClient.js
@@ -646,7 +646,7 @@ class OpenAIClient extends BaseClient {
configOptions.baseOptions = {
headers: {
'HTTP-Referer': 'https://librechat.ai',
- 'X-Title': 'LibreChat',
+ 'X-Title': 'EnricChat',
},
};
}
@@ -1090,7 +1090,7 @@ ${convo}
if (this.useOpenRouter) {
opts.defaultHeaders = {
'HTTP-Referer': 'https://librechat.ai',
- 'X-Title': 'LibreChat',
+ 'X-Title': 'EnricChat',
};
}
diff --git a/api/app/clients/tools/manifest.json b/api/app/clients/tools/manifest.json
index d2748cdea11..9fd8e2b50a6 100644
--- a/api/app/clients/tools/manifest.json
+++ b/api/app/clients/tools/manifest.json
@@ -21,12 +21,12 @@
{
"authField": "GOOGLE_CSE_ID",
"label": "Google CSE ID",
- "description": "This is your Google Custom Search Engine ID. For instructions on how to obtain this, see Our Docs ."
+ "description": "This is your Google Custom Search Engine ID. For instructions on how to obtain this, see Our Docs ."
},
{
"authField": "GOOGLE_SEARCH_API_KEY",
"label": "Google API Key",
- "description": "This is your Google Custom Search API Key. For instructions on how to obtain this, see Our Docs ."
+ "description": "This is your Google Custom Search API Key. For instructions on how to obtain this, see Our Docs ."
}
]
},
diff --git a/api/config/parsers.js b/api/config/parsers.js
index a3bab7d3cb0..51e9c052d0f 100644
--- a/api/config/parsers.js
+++ b/api/config/parsers.js
@@ -4,6 +4,7 @@ const traverse = require('traverse');
const SPLAT_SYMBOL = Symbol.for('splat');
const MESSAGE_SYMBOL = Symbol.for('message');
+const CONSOLE_JSON_LONG_STRING_LENGTH=parseInt(process.env.CONSOLE_JSON_LONG_STRING_LENGTH) || 255;
const sensitiveKeys = [
/^(sk-)[^\s]+/, // OpenAI API key pattern
@@ -211,7 +212,7 @@ const jsonTruncateFormat = winston.format((info) => {
const newObj = {};
Object.entries(obj).forEach(([key, value]) => {
if (typeof value === 'string') {
- newObj[key] = truncateLongStrings(value, 255);
+ newObj[key] = truncateLongStrings(value, CONSOLE_JSON_LONG_STRING_LENGTH);
} else {
newObj[key] = truncateObject(value);
}
diff --git a/api/package.json b/api/package.json
index e364b68eb9e..b40de9b6df9 100644
--- a/api/package.json
+++ b/api/package.json
@@ -18,7 +18,7 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/danny-avila/LibreChat.git"
+ "url": "git+https://github.com/enricai/LibreChat.git"
},
"keywords": [],
"author": "",
@@ -30,7 +30,7 @@
"~/*": "./*"
},
"bugs": {
- "url": "https://github.com/danny-avila/LibreChat/issues"
+ "url": "https://github.com/enricai/LibreChat/issues"
},
"homepage": "https://librechat.ai",
"dependencies": {
@@ -78,7 +78,7 @@
"meilisearch": "^0.38.0",
"mime": "^3.0.0",
"module-alias": "^2.2.3",
- "mongoose": "^8.8.3",
+ "mongoose": "^8.9.5",
"multer": "^1.4.5-lts.1",
"nanoid": "^3.3.7",
"nodejs-gpt": "^1.37.4",
diff --git a/api/server/controllers/agents/client.js b/api/server/controllers/agents/client.js
index e3c6dd5679c..02194cb544c 100644
--- a/api/server/controllers/agents/client.js
+++ b/api/server/controllers/agents/client.js
@@ -397,7 +397,7 @@ class AgentClient extends BaseClient {
// if (this.useOpenRouter) {
// opts.defaultHeaders = {
// 'HTTP-Referer': 'https://librechat.ai',
- // 'X-Title': 'LibreChat',
+ // 'X-Title': 'EnricChat',
// };
// }
diff --git a/api/server/controllers/assistants/v2.js b/api/server/controllers/assistants/v2.js
index 54f9a6fbc6b..74de1fa40b0 100644
--- a/api/server/controllers/assistants/v2.js
+++ b/api/server/controllers/assistants/v2.js
@@ -139,10 +139,11 @@ const updateAssistant = async ({ req, openai, assistant_id, updateData }) => {
}
if (hasFileSearch && !updateData.tool_resources?.file_search) {
+ const vectorStore = await openai.beta.assistants.vector_store.create(assistant_id);
updateData.tool_resources = {
...(updateData.tool_resources ?? {}),
file_search: {
- vector_store_ids: [],
+ vector_store_ids: [vectorStore.id],
},
};
}
@@ -175,10 +176,26 @@ const updateAssistant = async ({ req, openai, assistant_id, updateData }) => {
const addResourceFileId = async ({ req, openai, assistant_id, tool_resource, file_id }) => {
const assistant = await openai.beta.assistants.retrieve(assistant_id);
const { tool_resources = {} } = assistant;
+ const isFileSearch = tool_resource === ToolCallTypes.FILE_SEARCH;
+ if (isFileSearch) {
+ const vectorStore = await openai.beta.assistants.vector_store.create(assistant_id);
+ await openai.beta.assistants.vector_store.files.create(vectorStore.id, { file_id });
+ file_id = vectorStore.id;
+ }
+
if (tool_resources[tool_resource]) {
- tool_resources[tool_resource].file_ids.push(file_id);
+ if (isFileSearch) {
+ // only one vectordb per assistant is needed
+ tool_resources[tool_resource] = { vector_store_ids: [file_id] };
+ } else {
+ tool_resources[tool_resource].file_ids.push(file_id);
+ }
} else {
- tool_resources[tool_resource] = { file_ids: [file_id] };
+ if (isFileSearch) {
+ tool_resources[tool_resource] = { vector_store_ids: [file_id] };
+ } else {
+ tool_resources[tool_resource] = { file_ids: [file_id] };
+ }
}
delete assistant.id;
@@ -204,7 +221,14 @@ const addResourceFileId = async ({ req, openai, assistant_id, tool_resource, fil
const deleteResourceFileId = async ({ req, openai, assistant_id, tool_resource, file_id }) => {
const assistant = await openai.beta.assistants.retrieve(assistant_id);
const { tool_resources = {} } = assistant;
+ const isFileSearch = tool_resource === ToolCallTypes.FILE_SEARCH;
+ if (isFileSearch) {
+ const vectorStore = await openai.beta.assistants.vector_store.create(assistant_id);
+ await openai.beta.assistants.vector_store.files.del(vectorStore.id, { file_id });
+ }
+ // only one vectordb per assistant is needed, no need to delete it once it's
+ // created since it's OK to have a vector db with no docs
if (tool_resource && tool_resources[tool_resource]) {
const resource = tool_resources[tool_resource];
const index = resource.file_ids.indexOf(file_id);
diff --git a/api/server/routes/config.js b/api/server/routes/config.js
index f6669169acd..305ef379914 100644
--- a/api/server/routes/config.js
+++ b/api/server/routes/config.js
@@ -39,7 +39,7 @@ router.get('/', async function (req, res) {
try {
/** @type {TStartupConfig} */
const payload = {
- appTitle: process.env.APP_TITLE || 'LibreChat',
+ appTitle: process.env.APP_TITLE || 'EnricChat',
socialLogins: req.app.locals.socialLogins ?? defaultSocialLogins,
discordLoginEnabled: !!process.env.DISCORD_CLIENT_ID && !!process.env.DISCORD_CLIENT_SECRET,
facebookLoginEnabled:
diff --git a/api/server/routes/files/files.js b/api/server/routes/files/files.js
index c320f7705b2..b9c0fa03f90 100644
--- a/api/server/routes/files/files.js
+++ b/api/server/routes/files/files.js
@@ -18,6 +18,7 @@ const { getStrategyFunctions } = require('~/server/services/Files/strategies');
const { getOpenAIClient } = require('~/server/controllers/assistants/helpers');
const { loadAuthValues } = require('~/app/clients/tools/util');
const { getAgent } = require('~/models/Agent');
+const { getAssistant } = require('~/models/Assistant');
const { getFiles } = require('~/models/File');
const { logger } = require('~/config');
@@ -78,7 +79,7 @@ router.delete('/', async (req, res) => {
});
}
- /* Handle entity unlinking even if no valid files to delete */
+ /* Handle agent unlinking even if no valid files to delete */
if (req.body.agent_id && req.body.tool_resource && dbFiles.length === 0) {
const agent = await getAgent({
id: req.body.agent_id,
@@ -88,7 +89,21 @@ router.delete('/', async (req, res) => {
const agentFiles = files.filter((f) => toolResourceFiles.includes(f.file_id));
await processDeleteRequest({ req, files: agentFiles });
- res.status(200).json({ message: 'File associations removed successfully' });
+ res.status(200).json({ message: 'File associations removed successfully from agent' });
+ return;
+ }
+
+ /* Handle assistant unlinking even if no valid files to delete */
+ if (req.body.assistant_id && req.body.tool_resource && dbFiles.length === 0) {
+ const assistant = await getAssistant({
+ id: req.body.assistant_id,
+ });
+
+ const toolResourceFiles = assistant.tool_resources?.[req.body.tool_resource]?.file_ids ?? [];
+ const assistantFiles = files.filter((f) => toolResourceFiles.includes(f.file_id));
+
+ await processDeleteRequest({ req, files: assistantFiles });
+ res.status(200).json({ message: 'File associations removed successfully from assistant' });
return;
}
diff --git a/api/server/services/AuthService.js b/api/server/services/AuthService.js
index 49c3c4a17d9..b48249e3bc5 100644
--- a/api/server/services/AuthService.js
+++ b/api/server/services/AuthService.js
@@ -83,7 +83,7 @@ const sendVerificationEmail = async (user) => {
email: user.email,
subject: 'Verify your email',
payload: {
- appName: process.env.APP_TITLE || 'LibreChat',
+ appName: process.env.APP_TITLE || 'EnricChat',
name: user.name,
verificationLink: verificationLink,
year: new Date().getFullYear(),
@@ -255,7 +255,7 @@ const requestPasswordReset = async (req) => {
email: user.email,
subject: 'Password Reset Request',
payload: {
- appName: process.env.APP_TITLE || 'LibreChat',
+ appName: process.env.APP_TITLE || 'EnricChat',
name: user.name,
link: link,
year: new Date().getFullYear(),
@@ -308,7 +308,7 @@ const resetPassword = async (userId, token, password) => {
email: user.email,
subject: 'Password Reset Successfully',
payload: {
- appName: process.env.APP_TITLE || 'LibreChat',
+ appName: process.env.APP_TITLE || 'EnricChat',
name: user.name,
year: new Date().getFullYear(),
},
@@ -391,7 +391,7 @@ const resendVerificationEmail = async (req) => {
email: user.email,
subject: 'Verify your email',
payload: {
- appName: process.env.APP_TITLE || 'LibreChat',
+ appName: process.env.APP_TITLE || 'EnricChat',
name: user.name,
verificationLink: verificationLink,
year: new Date().getFullYear(),
diff --git a/api/server/services/Endpoints/azureAssistants/initialize.js b/api/server/services/Endpoints/azureAssistants/initialize.js
index fc8024af072..b35dc537954 100644
--- a/api/server/services/Endpoints/azureAssistants/initialize.js
+++ b/api/server/services/Endpoints/azureAssistants/initialize.js
@@ -53,6 +53,135 @@ class Files {
}
}
+class VectorStoreFiles {
+ constructor(client) {
+ this._client = client;
+ }
+
+ /**
+ * Create a vector store file
+ * [File](https://platform.openai.com/docs/api-reference/vector-stores-files) to an
+ * [Vector store](https://platform.openai.com/docs/api-reference/vector-stores).
+ */
+ create(vectorstoreId, body, options) {
+ return this._client.post(`/vector_stores/${vectorstoreId}/files`, {
+ body,
+ ...options,
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ }
+
+ /**
+ * Lists all vector store files
+ */
+ async list(vectorstoreId, options) {
+ // TODO paginate instead of setting a hard limit
+ return this._client.get(`/vector_stores/${vectorstoreId}`, {
+ query: { limit: 100 },
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ }
+
+ /**
+ * Retrieves a vector store file
+ */
+ retrieve(vectorstoreId, fileId, options) {
+ return this._client.get(`/vector_stores/${vectorstoreId}/files/${fileId}`, {
+ ...options,
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ }
+
+ /**
+ * Delete a vector store file
+ */
+ del(vectorstoreId, fileId, options) {
+ return this._client.delete(`/vector_stores/${vectorstoreId}/files/${fileId}`, {
+ ...options,
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ }
+}
+
+class VectorStore {
+ constructor(client) {
+ this._client = client;
+ this._assistants = {};
+ this.files = new VectorStoreFiles(client);
+ }
+
+ async _list(options) {
+ // TODO paginate instead of setting a hard limit
+ return this._client.get("/vector_stores", {
+ query: { limit: 100 },
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ }
+
+ async _retrieveForAssistant(assistantId, options) {
+ if (!this._assistants[assistantId]) {
+ this._assistants[assistantId] = {};
+ const vectorStores = await this._list(options);
+ const aVectorStore = (vectorStores?.data || []).find((vs) => {
+ return vs.name == this.name(assistantId);
+ });
+ if (aVectorStore) {
+ this._assistants[assistantId] = {[aVectorStore.name]: aVectorStore};
+ }
+ }
+
+ return this._assistants[assistantId][this.name(assistantId)]
+ }
+
+ name(assistantId) {
+ return `${assistantId}_vector_store`;
+ }
+
+ /**
+ * Create a vector store
+ * [Vector store](https://platform.openai.com/docs/api-reference/vector-stores).
+ */
+ async create(assistantId, options) {
+ const existingVectorStore = await this._retrieveForAssistant(assistantId, options);
+ if (existingVectorStore) {
+ return existingVectorStore;
+ }
+
+ const newVectorStore = await this._client.post(`/vector_stores`, {
+ body: { name: this.name(assistantId) },
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ this._assistants[assistantId] = {[newVectorStore.name]: newVectorStore};
+
+ return newVectorStore;
+ }
+
+ /**
+ * Retrieves a vector store
+ */
+ async retrieve(assistantId, options) {
+ const existingVectorStore = await this._retrieveForAssistant(assistantId, options);
+ if (existingVectorStore) {
+ return existingVectorStore;
+ }
+
+ return this._client.get(`/vector_stores/${this.name(assistantId)}`, {
+ ...options,
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ }
+
+ /**
+ * Deletes a vector store
+ */
+ del(assistantId, options) {
+ return this._client.delete(`/vector_stores/${this.name(assistantId)}`, {
+ ...options,
+ headers: { 'OpenAI-Beta': 'assistants=v1', ...options?.headers },
+ });
+ }
+}
+
const initializeClient = async ({ req, res, version, endpointOption, initAppClient = false }) => {
const { PROXY, OPENAI_ORGANIZATION, AZURE_ASSISTANTS_API_KEY, AZURE_ASSISTANTS_BASE_URL } =
process.env;
@@ -175,6 +304,7 @@ const initializeClient = async ({ req, res, version, endpointOption, initAppClie
});
openai.beta.assistants.files = new Files(openai);
+ openai.beta.assistants.vector_store = new VectorStore(openai);
openai.req = req;
openai.res = res;
diff --git a/api/server/services/Endpoints/openAI/llm.js b/api/server/services/Endpoints/openAI/llm.js
index 2587b242c99..3a3f943d886 100644
--- a/api/server/services/Endpoints/openAI/llm.js
+++ b/api/server/services/Endpoints/openAI/llm.js
@@ -60,14 +60,16 @@ function getLLMConfig(apiKey, options = {}) {
// Handle OpenRouter or custom reverse proxy
if (useOpenRouter || reverseProxyUrl === 'https://openrouter.ai/api/v1') {
- configOptions.baseURL = 'https://openrouter.ai/api/v1';
- configOptions.defaultHeaders = Object.assign(
- {
- 'HTTP-Referer': 'https://librechat.ai',
- 'X-Title': 'LibreChat',
- },
- headers,
- );
+ configOptions.basePath = 'https://openrouter.ai/api/v1';
+ configOptions.baseOptions = {
+ headers: Object.assign(
+ {
+ 'HTTP-Referer': 'https://librechat.ai',
+ 'X-Title': 'EnricChat',
+ },
+ headers,
+ ),
+ };
} else if (reverseProxyUrl) {
configOptions.baseURL = reverseProxyUrl;
if (headers) {
diff --git a/api/server/services/Files/process.js b/api/server/services/Files/process.js
index a5d9c8c1e05..acdfe5beea0 100644
--- a/api/server/services/Files/process.js
+++ b/api/server/services/Files/process.js
@@ -137,21 +137,29 @@ const processDeleteRequest = async ({ req, files }) => {
/** @type {Record} */
const client = { [FileSources.openai]: undefined, [FileSources.azure]: undefined };
const initializeClients = async () => {
- const openAIClient = await getOpenAIClient({
- req,
- overrideEndpoint: EModelEndpoint.assistants,
- });
- client[FileSources.openai] = openAIClient.openai;
+ try {
+ const openAIClient = await getOpenAIClient({
+ req,
+ overrideEndpoint: EModelEndpoint.assistants,
+ });
+ client[FileSources.openai] = openAIClient.openai;
+ } catch (error) {
+ logger.warn(`Could not init OpenAI client: ${error}`);
+ }
if (!req.app.locals[EModelEndpoint.azureOpenAI]?.assistants) {
return;
}
- const azureClient = await getOpenAIClient({
- req,
- overrideEndpoint: EModelEndpoint.azureAssistants,
- });
- client[FileSources.azure] = azureClient.openai;
+ try {
+ const azureClient = await getOpenAIClient({
+ req,
+ overrideEndpoint: EModelEndpoint.azureAssistants,
+ });
+ client[FileSources.azure] = azureClient.openai;
+ } catch (error) {
+ logger.warn(`Could not init Azure OpenAI client: ${error}`);
+ }
};
if (req.body.assistant_id !== undefined) {
diff --git a/api/server/services/start/assistants.js b/api/server/services/start/assistants.js
index b46edc676b9..a855cf8c9c8 100644
--- a/api/server/services/start/assistants.js
+++ b/api/server/services/start/assistants.js
@@ -11,7 +11,7 @@ const { logger } = require('~/config');
*/
function azureAssistantsDefaults() {
return {
- capabilities: [Capabilities.tools, Capabilities.actions, Capabilities.code_interpreter],
+ capabilities: [Capabilities.tools, Capabilities.actions, Capabilities.code_interpreter, Capabilities.retrieval],
version: defaultAssistantsVersion.azureAssistants,
};
}
diff --git a/charts/librechat/values.yaml b/charts/librechat/values.yaml
index c21f84586a6..6908e049e63 100644
--- a/charts/librechat/values.yaml
+++ b/charts/librechat/values.yaml
@@ -5,7 +5,7 @@
replicaCount: 1
image:
- repository: ghcr.io/danny-avila/librechat
+ repository: ghcr.io/enricai/librechat
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "latest"
@@ -95,7 +95,7 @@ config:
env:
# Full list of possible values
- # https://github.com/danny-avila/LibreChat/blob/main/.env.example
+ # https://github.com/enricai/LibreChat/blob/main/.env.example
ALLOW_EMAIL_LOGIN: "true"
ALLOW_REGISTRATION: "true"
ALLOW_SOCIAL_LOGIN: "false"
diff --git a/client/index.html b/client/index.html
index c72d3951cbf..3c74a7db256 100644
--- a/client/index.html
+++ b/client/index.html
@@ -6,7 +6,7 @@
- LibreChat
+ EnricChat
diff --git a/client/nginx.conf b/client/nginx.conf
index c91c47a23f0..28a742d30eb 100644
--- a/client/nginx.conf
+++ b/client/nginx.conf
@@ -1,27 +1,20 @@
-# Secure default configuration generated by Mozilla SSL Configuration Generator
-# generated 2024-01-21, Mozilla Guideline v5.7, nginx 1.24.0, OpenSSL 3.1.4, intermediate configuration
-# https://ssl-config.mozilla.org/#server=nginx&version=1.24.0&config=intermediate&openssl=3.1.4&guideline=5.7
-
server {
listen 80 default_server;
listen [::]:80 default_server;
- # To Configure SSL, comment all lines within the Non-SSL section and uncomment all lines under the SSL section.
- ######################################## Non-SSL ########################################
server_name localhost;
-
- # https://docs.nginx.com/nginx/admin-guide/web-server/compression/
- # gzip on;
- # gzip_vary on;
- # gzip_proxied any;
- # gzip_comp_level 6;
- # gzip_buffers 16 8k;
- # gzip_http_version 1.1;
- # gzip_types text/css application/javascript application/json application/octet-stream;
- # Increase the client_max_body_size to allow larger file uploads
- # The default limits for image uploads as of 11/22/23 is 20MB/file, and 25MB/request
- client_max_body_size 25M;
+ client_max_body_size 1024M;
+ proxy_read_timeout 300s;
+
+ # https://docs.nginx.com/nginx/admin-guide/web-server/compression/
+ gzip on;
+ gzip_vary on;
+ gzip_proxied any;
+ gzip_comp_level 6;
+ gzip_buffers 16 8k;
+ gzip_http_version 1.1;
+ gzip_types text/css application/javascript application/json application/octet-stream;
location /api/ {
proxy_pass http://api:3080$request_uri;
@@ -30,65 +23,4 @@ server {
location / {
proxy_pass http://api:3080/;
}
-
- ######################################## SSL ########################################
-# # Redirect all http traffic to https
-# location / {
-# return 301 https://$host$request_uri;
-# }
}
-
-#server {
-# listen 443 ssl http2;
-# listen [::]:443 ssl http2;
-
-# https://docs.nginx.com/nginx/admin-guide/web-server/compression/
-# gzip on;
-# gzip_vary on;
-# gzip_proxied any;
-# gzip_comp_level 6;
-# gzip_buffers 16 8k;
-# gzip_http_version 1.1;
-# gzip_types text/css application/javascript application/json application/octet-stream;
-
-# ssl_certificate /etc/nginx/ssl/nginx.crt;
-# ssl_certificate_key /etc/nginx/ssl/nginx.key;
-# ssl_session_timeout 1d;
-# ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
-# ssl_session_tickets off;
-
-# # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/nginx/ssl/dhparam
-# ssl_dhparam /etc/nginx/ssl/dhparam;
-
-# # intermediate configuration
-# ssl_protocols TLSv1.2 TLSv1.3;
-# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
-# ssl_prefer_server_ciphers off;
-
-# # HSTS (ngx_http_headers_module is required) (63072000 seconds)
-# add_header Strict-Transport-Security "max-age=63072000" always;
-
-# # OCSP stapling
-# ssl_stapling on;
-# ssl_stapling_verify on;
-
-# # verify chain of trust of OCSP response using Root CA and Intermediate certs
-# ssl_trusted_certificate /etc/nginx/ssl/ca.crt;
-
-# # replace with the IP address of your resolver
-# resolver 127.0.0.1;
-
-# server_name localhost;
-
-# # Increase the client_max_body_size to allow larger file uploads
-# # The default limits for image uploads as of 11/22/23 is 20MB/file, and 25MB/request
-# client_max_body_size 25M;
-
-# location /api {
-# proxy_pass http://api:3080/api;
-# }
-
-# location / {
-# proxy_pass http://api:3080;
-# }
-#}
diff --git a/client/package.json b/client/package.json
index 029ca3cdee1..e67368bf0eb 100644
--- a/client/package.json
+++ b/client/package.json
@@ -18,13 +18,13 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/danny-avila/LibreChat.git"
+ "url": "git+https://github.com/enricai/LibreChat.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
- "url": "https://github.com/danny-avila/LibreChat/issues"
+ "url": "https://github.com/enricai/LibreChat/issues"
},
"homepage": "https://librechat.ai",
"dependencies": {
diff --git a/client/public/assets/apple-touch-icon-180x180.png b/client/public/assets/apple-touch-icon-180x180.png
index 91dde5d139d..932a63e5215 100644
Binary files a/client/public/assets/apple-touch-icon-180x180.png and b/client/public/assets/apple-touch-icon-180x180.png differ
diff --git a/client/public/assets/favicon-16x16.png b/client/public/assets/favicon-16x16.png
index 03975d8ec0b..787b1355d8a 100644
Binary files a/client/public/assets/favicon-16x16.png and b/client/public/assets/favicon-16x16.png differ
diff --git a/client/public/assets/favicon-32x32.png b/client/public/assets/favicon-32x32.png
index df89fb33b01..85c444ff33d 100644
Binary files a/client/public/assets/favicon-32x32.png and b/client/public/assets/favicon-32x32.png differ
diff --git a/client/public/assets/logo.png b/client/public/assets/logo.png
new file mode 100644
index 00000000000..f20e3609b7d
Binary files /dev/null and b/client/public/assets/logo.png differ
diff --git a/client/public/fonts/ClashDisplay-Light.ttf b/client/public/fonts/ClashDisplay-Light.ttf
new file mode 100644
index 00000000000..b4f37110117
Binary files /dev/null and b/client/public/fonts/ClashDisplay-Light.ttf differ
diff --git a/client/public/fonts/ClashDisplay-Medium.ttf b/client/public/fonts/ClashDisplay-Medium.ttf
new file mode 100644
index 00000000000..9e704d1a4de
Binary files /dev/null and b/client/public/fonts/ClashDisplay-Medium.ttf differ
diff --git a/client/public/fonts/ClashDisplay-Regular.ttf b/client/public/fonts/ClashDisplay-Regular.ttf
new file mode 100644
index 00000000000..42376646ba7
Binary files /dev/null and b/client/public/fonts/ClashDisplay-Regular.ttf differ
diff --git a/client/public/fonts/ClashDisplay-Semibold.ttf b/client/public/fonts/ClashDisplay-Semibold.ttf
new file mode 100644
index 00000000000..6715249c537
Binary files /dev/null and b/client/public/fonts/ClashDisplay-Semibold.ttf differ
diff --git a/client/public/fonts/ClashDisplay-Variable.ttf b/client/public/fonts/ClashDisplay-Variable.ttf
new file mode 100644
index 00000000000..24f060c48e2
Binary files /dev/null and b/client/public/fonts/ClashDisplay-Variable.ttf differ
diff --git a/client/public/fonts/DMSans-Bold.ttf b/client/public/fonts/DMSans-Bold.ttf
new file mode 100644
index 00000000000..e70172a067f
Binary files /dev/null and b/client/public/fonts/DMSans-Bold.ttf differ
diff --git a/client/public/fonts/DMSans-BoldItalic.ttf b/client/public/fonts/DMSans-BoldItalic.ttf
new file mode 100644
index 00000000000..8b972ca08ca
Binary files /dev/null and b/client/public/fonts/DMSans-BoldItalic.ttf differ
diff --git a/client/public/fonts/DMSans-Italic.ttf b/client/public/fonts/DMSans-Italic.ttf
new file mode 100644
index 00000000000..b965526a842
Binary files /dev/null and b/client/public/fonts/DMSans-Italic.ttf differ
diff --git a/client/public/fonts/DMSans-Medium.ttf b/client/public/fonts/DMSans-Medium.ttf
new file mode 100644
index 00000000000..71b2277252b
Binary files /dev/null and b/client/public/fonts/DMSans-Medium.ttf differ
diff --git a/client/public/fonts/DMSans-MediumItalic.ttf b/client/public/fonts/DMSans-MediumItalic.ttf
new file mode 100644
index 00000000000..d3293d6641e
Binary files /dev/null and b/client/public/fonts/DMSans-MediumItalic.ttf differ
diff --git a/client/public/fonts/DMSans-Regular.ttf b/client/public/fonts/DMSans-Regular.ttf
new file mode 100644
index 00000000000..cad73f073f3
Binary files /dev/null and b/client/public/fonts/DMSans-Regular.ttf differ
diff --git a/client/src/components/Auth/AuthLayout.tsx b/client/src/components/Auth/AuthLayout.tsx
index 6df73d2cf94..7b8707d0e61 100644
--- a/client/src/components/Auth/AuthLayout.tsx
+++ b/client/src/components/Auth/AuthLayout.tsx
@@ -45,7 +45,7 @@ function AuthLayout({
return (
{localize('com_auth_error_invalid_reset_token')}{' '}
-
+
{localize('com_auth_click_here')}
{' '}
{localize('com_auth_to_try_again')}
@@ -61,11 +61,11 @@ function AuthLayout({
-
+
@@ -78,7 +78,7 @@ function AuthLayout({
{!hasStartupConfigError && !isFetching && (
{header}
diff --git a/client/src/components/Auth/Footer.tsx b/client/src/components/Auth/Footer.tsx
index 8d797176838..fd09e9f5b28 100644
--- a/client/src/components/Auth/Footer.tsx
+++ b/client/src/components/Auth/Footer.tsx
@@ -11,7 +11,7 @@ function Footer({ startupConfig }: { startupConfig: TStartupConfig | null | unde
const privacyPolicyRender = privacyPolicy?.externalUrl && (
{' '}
{localize('com_auth_no_account')}{' '}
-
+
{localize('com_auth_sign_up')}
diff --git a/client/src/components/Auth/LoginForm.tsx b/client/src/components/Auth/LoginForm.tsx
index 0c532abe408..67877895251 100644
--- a/client/src/components/Auth/LoginForm.tsx
+++ b/client/src/components/Auth/LoginForm.tsx
@@ -108,7 +108,7 @@ const LoginForm: React.FC = ({ onSubmit, startupConfig, error,
className="
absolute start-3 top-1.5 z-10 origin-[0] -translate-y-4 scale-75 transform bg-surface-primary px-2 text-sm text-text-secondary-alt duration-200
peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:scale-100
- peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-green-600 dark:peer-focus:text-green-500
+ peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-secondary dark:peer-focus:text-primary
rtl:peer-focus:left-auto rtl:peer-focus:translate-x-1/4
"
>
@@ -143,7 +143,7 @@ const LoginForm: React.FC = ({ onSubmit, startupConfig, error,
className="
absolute start-3 top-1.5 z-10 origin-[0] -translate-y-4 scale-75 transform bg-surface-primary px-2 text-sm text-text-secondary-alt duration-200
peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:scale-100
- peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-green-600 dark:peer-focus:text-green-500
+ peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-secondary dark:peer-focus:text-primary
rtl:peer-focus:left-auto rtl:peer-focus:translate-x-1/4
"
>
@@ -153,10 +153,7 @@ const LoginForm: React.FC = ({ onSubmit, startupConfig, error,
{renderError('password')}
{startupConfig.passwordResetEnabled && (
-
+
{localize('com_auth_password_forgot')}
)}
diff --git a/client/src/components/Auth/Registration.tsx b/client/src/components/Auth/Registration.tsx
index 4ae4e03b793..8a85f3558be 100644
--- a/client/src/components/Auth/Registration.tsx
+++ b/client/src/components/Auth/Registration.tsx
@@ -81,7 +81,7 @@ const Registration: React.FC = () => {
className="
absolute start-3 top-1.5 z-10 origin-[0] -translate-y-4 scale-75 transform bg-surface-primary px-2 text-sm text-text-secondary-alt duration-200
peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:scale-100
- peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-green-500
+ peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-primary
rtl:peer-focus:left-auto rtl:peer-focus:translate-x-1/4
"
>
@@ -197,11 +197,7 @@ const Registration: React.FC = () => {
{localize('com_auth_already_have_account')}{' '}
-
+
{localize('com_auth_login')}
diff --git a/client/src/components/Auth/RequestPasswordReset.tsx b/client/src/components/Auth/RequestPasswordReset.tsx
index 1010c90a98d..d0a4b80c841 100644
--- a/client/src/components/Auth/RequestPasswordReset.tsx
+++ b/client/src/components/Auth/RequestPasswordReset.tsx
@@ -21,14 +21,13 @@ const BodyTextWrapper: FC<{ children: ReactNode }> = ({ children }) => {
const ResetPasswordBodyText = () => {
const localize = useLocalize();
return (
-
);
diff --git a/client/src/components/Auth/ResetPassword.tsx b/client/src/components/Auth/ResetPassword.tsx
index 3039e81c296..66916281a9c 100644
--- a/client/src/components/Auth/ResetPassword.tsx
+++ b/client/src/components/Auth/ResetPassword.tsx
@@ -100,7 +100,7 @@ function ResetPassword() {
className="
absolute start-3 top-1.5 z-10 origin-[0] -translate-y-4 scale-75 transform bg-surface-primary px-2 text-sm text-text-secondary-alt duration-200
peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:scale-100
- peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-green-500
+ peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-primary
rtl:peer-focus:left-auto rtl:peer-focus:translate-x-1/4
"
>
@@ -135,7 +135,7 @@ function ResetPassword() {
className="
absolute start-3 top-1.5 z-10 origin-[0] -translate-y-4 scale-75 transform bg-surface-primary px-2 text-sm text-text-secondary-alt duration-200
peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:scale-100
- peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-green-500
+ peer-focus:top-1.5 peer-focus:-translate-y-4 peer-focus:scale-75 peer-focus:px-2 peer-focus:text-primary
rtl:peer-focus:left-auto rtl:peer-focus:translate-x-1/4
"
>
diff --git a/client/src/components/Auth/VerifyEmail.tsx b/client/src/components/Auth/VerifyEmail.tsx
index acb5abe5ad9..99e87652d13 100644
--- a/client/src/components/Auth/VerifyEmail.tsx
+++ b/client/src/components/Auth/VerifyEmail.tsx
@@ -116,7 +116,7 @@ function RequestPasswordReset() {
{localize('com_auth_email_verification_in_progress')}
-
+
);
diff --git a/client/src/components/Chat/Footer.tsx b/client/src/components/Chat/Footer.tsx
index b534aee0188..6c39ead7b0c 100644
--- a/client/src/components/Chat/Footer.tsx
+++ b/client/src/components/Chat/Footer.tsx
@@ -37,7 +37,7 @@ export default function Footer({ className }: { className?: string }) {
const mainContentParts = (
typeof config?.customFooter === 'string'
? config.customFooter
- : '[LibreChat ' +
+ : '[EnricChat ' +
Constants.VERSION +
'](https://librechat.ai) - ' +
localize('com_ui_latest_footer')
diff --git a/client/src/components/Chat/Input/Files/FileUpload.tsx b/client/src/components/Chat/Input/Files/FileUpload.tsx
index 506f50c01de..de3b97b6bd4 100644
--- a/client/src/components/Chat/Input/Files/FileUpload.tsx
+++ b/client/src/components/Chat/Input/Files/FileUpload.tsx
@@ -45,7 +45,7 @@ const FileUpload: React.FC = ({
if (validator) {
setStatus('success');
- setStatusColor('text-green-500 dark:text-green-500');
+ setStatusColor('text-primary dark:text-primary');
}
onFileSelected(jsonData);
@@ -66,7 +66,7 @@ const FileUpload: React.FC = ({
[] = [
if (source === FileSources.openai) {
return (
-
+
{'OpenAI'}
);
diff --git a/client/src/components/Chat/Messages/Content/FinishedIcon.tsx b/client/src/components/Chat/Messages/Content/FinishedIcon.tsx
index 2d47833156b..5d9c9f8e79c 100644
--- a/client/src/components/Chat/Messages/Content/FinishedIcon.tsx
+++ b/client/src/components/Chat/Messages/Content/FinishedIcon.tsx
@@ -1,7 +1,7 @@
export default function FinishedIcon() {
return (
diff --git a/client/src/components/Chat/Messages/Content/ProgressCircle.tsx b/client/src/components/Chat/Messages/Content/ProgressCircle.tsx
index 60704b47057..cb445baec34 100644
--- a/client/src/components/Chat/Messages/Content/ProgressCircle.tsx
+++ b/client/src/components/Chat/Messages/Content/ProgressCircle.tsx
@@ -12,10 +12,10 @@ export default function ProgressCircle({
width="120"
height="120"
viewBox="0 0 120 120"
- className="absolute left-1/2 top-1/2 h-[23px] w-[23px] -translate-x-1/2 -translate-y-1/2 text-brand-purple"
+ className="absolute left-1/2 top-1/2 h-[23px] w-[23px] -translate-x-1/2 -translate-y-1/2 text-brand-orange"
>
-
+
{localize('com_ui_versions')}
@@ -60,7 +60,7 @@ const PromptVersions = ({
className={cn(
'w-fit border border-transparent bg-blue-100 text-blue-500 dark:border-blue-500 dark:bg-transparent dark:text-blue-500',
tag === 'production' &&
- 'bg-green-100 text-green-500 dark:border-green-500 dark:bg-transparent dark:text-green-500',
+ 'bg-green-100 text-primary dark:border-green-500 dark:bg-transparent dark:text-primary',
)}
labelClassName="flex m-0 justify-center gap-1"
LabelNode={
diff --git a/client/src/components/ui/Tag.tsx b/client/src/components/ui/Tag.tsx
index 38660d11c4e..d82b722a31b 100644
--- a/client/src/components/ui/Tag.tsx
+++ b/client/src/components/ui/Tag.tsx
@@ -19,7 +19,7 @@ const TagPrimitiveRoot = React.forwardRef(
ref={ref}
{...props}
className={cn(
- 'flex max-h-8 items-center overflow-y-hidden rounded-3xl border-2 border-green-600 bg-green-600/20 text-xs text-green-600 dark:text-white',
+ 'flex max-h-8 items-center overflow-y-hidden rounded-3xl border-2 border-green-600 bg-green-600/20 text-xs text-secondary dark:text-white',
className,
)}
>
diff --git a/client/src/localization/languages/Eng.ts b/client/src/localization/languages/Eng.ts
index 64aa137140a..ec04caa2255 100644
--- a/client/src/localization/languages/Eng.ts
+++ b/client/src/localization/languages/Eng.ts
@@ -247,7 +247,7 @@ export default {
com_ui_entries: 'Entries',
com_ui_pay_per_call: 'All AI conversations in one place. Pay per call and not per month',
com_ui_new_footer: 'All AI conversations in one place.',
- com_ui_latest_footer: 'Every AI for Everyone.',
+ com_ui_latest_footer: 'AI for Humanity.',
com_ui_enter: 'Enter',
com_ui_submit: 'Submit',
com_ui_zoom: 'Zoom',
diff --git a/client/src/localization/languages/Es.ts b/client/src/localization/languages/Es.ts
index a1627a5b5d5..70d8b8a0dea 100644
--- a/client/src/localization/languages/Es.ts
+++ b/client/src/localization/languages/Es.ts
@@ -808,7 +808,7 @@ export default {
com_ui_upload_invalid:
'Archivo no válido para subir. Debe ser una imagen que no exceda el límite',
- com_ui_latest_footer: 'IA para todos.',
+ com_ui_latest_footer: 'IA para la Humanidad.',
com_ui_renaming_var: 'Renombrando "{0}"',
diff --git a/client/src/localization/languages/Jp.ts b/client/src/localization/languages/Jp.ts
index c2fd0883f76..3568995bef3 100644
--- a/client/src/localization/languages/Jp.ts
+++ b/client/src/localization/languages/Jp.ts
@@ -192,7 +192,7 @@ export default {
com_ui_entries: 'エントリー',
com_ui_pay_per_call: 'すべてのAIモデルを1つの場所で。支払いは使った分だけ',
com_ui_new_footer: 'すべてのAIモデルを1つの場所で。',
- com_ui_latest_footer: 'Every AI for Everyone.',
+ com_ui_latest_footer: 'AI for Humanity.',
com_ui_enter: '入力',
com_ui_submit: '送信する',
com_ui_none_selected: '選択されていません',
diff --git a/client/src/localization/languages/Zh.ts b/client/src/localization/languages/Zh.ts
index 928550d79d2..e675ba9c52c 100644
--- a/client/src/localization/languages/Zh.ts
+++ b/client/src/localization/languages/Zh.ts
@@ -184,7 +184,7 @@ export default {
com_ui_entries: '项',
com_ui_pay_per_call: '所有对话都将集中在一处。按会话次数计费,而不是按月付费',
com_ui_new_footer: '所有对话都将集中在一处。',
- com_ui_latest_footer: 'Every AI for Everyone.',
+ com_ui_latest_footer: 'AI for Humanity.',
com_ui_enter: '进入',
com_ui_submit: '提交',
com_ui_none_selected: '未选择任何项目',
diff --git a/client/src/routes/Layouts/Startup.tsx b/client/src/routes/Layouts/Startup.tsx
index 5e8e431f8be..8200b4adf88 100644
--- a/client/src/routes/Layouts/Startup.tsx
+++ b/client/src/routes/Layouts/Startup.tsx
@@ -37,7 +37,7 @@ export default function StartupLayout({ isAuthenticated }: { isAuthenticated?: b
}, [isAuthenticated, navigate, data]);
useEffect(() => {
- document.title = startupConfig?.appTitle || 'LibreChat';
+ document.title = startupConfig?.appTitle || 'EnricChat';
}, [startupConfig?.appTitle]);
useEffect(() => {
diff --git a/client/src/style.css b/client/src/style.css
index e190603fd98..a7d042cc281 100644
--- a/client/src/style.css
+++ b/client/src/style.css
@@ -270,209 +270,85 @@ html {
}
@font-face {
- font-display: swap;
- font-family: Inter;
+ font-family: "ClashDisplay";
+ src: url("$fonts/ClashDisplay-Light.ttf") format("truetype");
+ font-weight: 300;
font-style: normal;
- font-weight: 400;
- src: url('$fonts/Inter-Regular.woff2') format('woff2');
- size-adjust: 94%;
-}
-
-@font-face {
font-display: swap;
- font-family: Inter;
- font-style: italic;
- font-weight: 400;
- src: url('$fonts/Inter-Italic.woff2') format('woff2');
- size-adjust: 94%;
}
@font-face {
- font-display: swap;
- font-family: Inter;
+ font-family: "ClashDisplay";
+ src: url("$fonts/ClashDisplay-Regular.ttf") format("truetype");
+ font-weight: 400;
font-style: normal;
- font-weight: 500;
- src: url('$fonts/Inter-SemiBold.woff2') format('woff2');
- size-adjust: 94%;
-}
-
-@font-face {
font-display: swap;
- font-family: Inter;
- font-style: italic;
- font-weight: 500;
- src: url('$fonts/Inter-SemiBoldItalic.woff2') format('woff2');
- size-adjust: 94%;
}
@font-face {
- font-display: swap;
- font-family: Inter;
+ font-family: "ClashDisplay";
+ src: url("$fonts/ClashDisplay-Medium.ttf") format("truetype");
+ font-weight: 500;
font-style: normal;
- font-weight: 600;
- src: url('$fonts/Inter-Bold.woff2') format('woff2');
- size-adjust: 94%;
-}
-
-@font-face {
font-display: swap;
- font-family: Inter;
- font-style: italic;
- font-weight: 600;
- src: url('$fonts/Inter-BoldItalic.woff2') format('woff2');
- size-adjust: 94%;
}
@font-face {
- font-display: swap;
- font-family: Roboto Mono;
+ font-family: "ClashDisplay";
+ src: url("$fonts/ClashDisplay-Semibold.ttf") format("truetype");
+ font-weight: 600;
font-style: normal;
- font-weight: 400;
- src: url('$fonts/roboto-mono-latin-400-normal.woff2') format('woff2');
-}
-
-@font-face {
font-display: swap;
- font-family: Roboto Mono;
- font-style: normal;
- font-weight: 700;
- src: url('$fonts/roboto-mono-latin-700-normal.woff2') format('woff2');
}
@font-face {
- font-display: swap;
- font-family: Roboto Mono;
- font-style: italic;
- font-weight: 400;
- src: url('$fonts/roboto-mono-latin-400-italic.woff2') format('woff2');
-}
-
-/*
-
-The default ChatGPT fonts, according to OpenAI's brand guidelines, are proprietary and require appropriate font license according to your use case.
-
-They can be purchased here: https://klim.co.nz/buy/soehne/
-
-The fonts in question are (9 total):
-
-> - Söhne (Buch Kursiv, Buch, Halbfett Kursiv, Halbfett, Kraftig Kursiv, Kraftig, Mono Buch Kursiv, Mono Buch, Mono Halbfett)
-
-If you have purchased a license, you can use the commented-out `@font-face` declarations below to include them in your project.
-
-Step 1: Buy whatever license applies to you and allows use of `.woff2` font files (likely web font license).
-Step 2: Place them in ./client/public/fonts/ directory.
-Step 3: Replace the current `fontFamily` config in ./client/tailwind.config.cjs with the following:
-
-```
- fontFamily: {
- sans: ['Söhne', 'sans-serif'],
- mono: ['Söhne Mono', 'monospace'],
- },
-```
-
-Step 4: Uncomment all Söhne font-face declarations below.
-Step 5: rebuild frontend code: `npm run frontend` (or rebuild docker).
-
-*/
-
-/* @font-face {
- font-display: swap;
- font-family: Söhne;
+ font-family: "DMSans";
+ src: url("$fonts/DMSans-Bold.ttf") format("truetype");
+ font-weight: 700;
font-style: normal;
- font-weight: 400;
- src: url("$fonts/soehne-buch.woff2") format("woff2")
-}
-
-@font-face {
font-display: swap;
- font-family: Söhne;
- font-style: italic;
- font-weight: 400;
- src: url("$fonts/soehne-buch-kursiv.woff2") format("woff2")
}
@font-face {
+ font-family: "DMSans";
+ src: url("$fonts/DMSans-BoldItalic.ttf") format("truetype");
+ font-weight: 700;
+ font-style: italic;
font-display: swap;
- font-family: Söhne;
- font-style: normal;
- font-weight: 500;
- src: url("$fonts/soehne-kraftig.woff2") format("woff2")
}
@font-face {
- font-display: swap;
- font-family: Söhne;
- font-style: italic;
+ font-family: "DMSans";
+ src: url("$fonts/DMSans-Medium.ttf") format("truetype");
font-weight: 500;
- src: url("$fonts/soehne-kraftig-kursiv.woff2") format("woff2")
-}
-
-@font-face {
- font-display: swap;
- font-family: Söhne;
font-style: normal;
- font-weight: 600;
- src: url("$fonts/soehne-halbfett.woff2") format("woff2")
-}
-
-@font-face {
font-display: swap;
- font-family: Söhne;
- font-style: italic;
- font-weight: 600;
- src: url("$fonts/soehne-halbfett-kursiv.woff2") format("woff2")
}
@font-face {
+ font-family: "DMSans";
+ src: url("$fonts/DMSans-MediumItalic.ttf") format("truetype");
+ font-weight: 500;
+ font-style: italic;
font-display: swap;
- font-family: Söhne Mono;
- font-style: normal;
- font-weight: 400;
- src: url("$fonts/soehne-mono-buch.woff2") format("woff2")
}
@font-face {
- font-display: swap;
- font-family: Söhne Mono;
+ font-family: "DMSans";
+ src: url("$fonts/DMSans-Regular.ttf") format("truetype");
+ font-weight: 400;
font-style: normal;
- font-weight: 700;
- src: url("$fonts/soehne-mono-halbfett.woff2") format("woff2")
+ font-display: swap;
}
@font-face {
- font-display: swap;
- font-family: Söhne Mono;
- font-style: italic;
+ font-family: "DMSans";
+ src: url("$fonts/DMSans-Italic.ttf") format("truetype");
font-weight: 400;
- src: url("$fonts/soehne-mono-buch-kursiv.woff2") format("woff2")
-} */
-
-/* * {
- box-sizing: border-box;
- outline: 1px solid limegreen !important;
-} */
-
-/* p small {
- opacity: 0;
- animation: fadeIn 3s ease forwards;
+ font-style: italic;
+ font-display: swap;
}
-@keyframes fadeIn {
- from {
- opacity: 0;
- transform: translateY(-10px);
- }
- to {
- opacity: 1;
- transform: translateY(0);
- }
-} */
-
-/* .LazyLoad {
- opacity: 0;
- transition: all 1s ease-in-out;
-} */
-
select {
--tw-shadow: 0 0 transparent;
-webkit-appearance: none;
@@ -1082,7 +958,7 @@ pre {
code,
pre {
- font-family: Consolas, Söhne Mono, Monaco, Andale Mono, Ubuntu Mono, monospace !important;
+ font-family: ClashDisplay,DMSans,sans-serif;
}
code[class='language-plaintext'] {
white-space: pre-line;
@@ -1868,8 +1744,7 @@ button.scroll-convo {
content: '⬤';
width: 12px;
height: 12px;
- font-family: system-ui, Inter, Söhne Circle, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell,
- Noto Sans, sans-serif;
+ font-family: ClashDisplay,DMSans,sans-serif;
line-height: normal;
margin-left: 0.25rem;
vertical-align: middle;
@@ -1879,8 +1754,7 @@ button.scroll-convo {
@supports (selector(:has(*))) {
.result-streaming > :is(ul, ol):last-child > li:last-child:not(:has(> :is(ul, ol, pre))):after {
content: '⬤';
- font-family: system-ui, Inter, Söhne Circle, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell,
- Noto Sans, sans-serif;
+ font-family: ClashDisplay,DMSans,sans-serif;
line-height: normal;
margin-left: 0.25rem;
vertical-align: middle;
@@ -1895,8 +1769,7 @@ button.scroll-convo {
.result-streaming > ol:last-child > li:last-child:after,
.result-streaming > ul:last-child > li:last-child:after {
content: '⬤';
- font-family: system-ui, Inter, Söhne Circle, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell,
- Noto Sans, sans-serif;
+ font-family: ClashDisplay,DMSans,sans-serif;
line-height: normal;
margin-left: 0.25rem;
vertical-align: middle;
diff --git a/client/tailwind.config.cjs b/client/tailwind.config.cjs
index 17325a9cf4f..6eef0e375b3 100644
--- a/client/tailwind.config.cjs
+++ b/client/tailwind.config.cjs
@@ -7,13 +7,9 @@ module.exports = {
darkMode: ['class'],
theme: {
fontFamily: {
- sans: ['Inter', 'sans-serif'],
- mono: ['Roboto Mono', 'monospace'],
+ sans: ['ClashDisplay', 'sans-serif'],
+ mono: ['DMSans', 'sans-serif'],
},
- // fontFamily: {
- // sans: ['Söhne', 'sans-serif'],
- // mono: ['Söhne Mono', 'monospace'],
- // },
extend: {
width: {
authPageWidth: '370px',
@@ -62,6 +58,7 @@ module.exports = {
},
'brand-purple': '#ab68ff',
'presentation': 'var(--presentation)',
+ 'brand-orange': '#ff5810',
'text-primary': 'var(--text-primary)',
'text-secondary': 'var(--text-secondary)',
'text-secondary-alt': 'var(--text-secondary-alt)',
diff --git a/client/vite.config.ts b/client/vite.config.ts
index a349e1fbcdb..8431ceb9a4c 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -54,6 +54,7 @@ export default defineConfig({
react(),
nodePolyfills(),
VitePWA({
+ includeManifestIcons: false,
injectRegister: 'auto', // 'auto' | 'manual' | 'disabled'
registerType: 'autoUpdate', // 'prompt' | 'autoUpdate'
devOptions: {
@@ -65,8 +66,8 @@ export default defineConfig({
navigateFallbackDenylist: [/^\/oauth/],
},
manifest: {
- name: 'LibreChat',
- short_name: 'LibreChat',
+ name: 'EnricChat',
+ short_name: 'EnricChat',
start_url: '/',
display: 'standalone',
background_color: '#000000',
diff --git a/config/deployed-update.js b/config/deployed-update.js
index 5b1072f8414..e68e0e70607 100644
--- a/config/deployed-update.js
+++ b/config/deployed-update.js
@@ -41,7 +41,7 @@ const shouldRebase = process.argv.includes('--rebase');
execSync(downCommand, { stdio: 'inherit' });
console.purple('Removing all tags for LibreChat `deployed` images...');
- const repositories = ['ghcr.io/danny-avila/librechat-dev-api', 'librechat-client'];
+ const repositories = ['ghcr.io/enricai/librechat-dev-api', 'librechat-client'];
repositories.forEach((repo) => {
const tags = execSync(`sudo docker images ${repo} -q`, { encoding: 'utf8' })
.split('\n')
diff --git a/deploy-compose.yml b/deploy-compose.yml
index 9c2936a9798..f93ac820d91 100644
--- a/deploy-compose.yml
+++ b/deploy-compose.yml
@@ -1,20 +1,19 @@
-version: "3.8"
services:
api:
- # build:
- # context: .
- # dockerfile: Dockerfile.multi
- # target: api-build
- image: ghcr.io/danny-avila/librechat-dev-api:latest
- container_name: LibreChat-API
+ build:
+ context: .
+ dockerfile: Dockerfile.multi
+ target: api-build
+ image: api-build
+ container_name: ai.enric.chat.api
ports:
- 3080:3080
depends_on:
- mongodb
- rag_api
- restart: always
extra_hosts:
- "host.docker.internal:host-gateway"
+ restart: always
env_file:
- .env
environment:
@@ -30,20 +29,34 @@ services:
target: /app/librechat.yaml
- ./images:/app/client/public/images
- ./logs:/app/api/logs
-
+ labels:
+ com.datadoghq.ad.logs: '[{
+ "source": "ai.enric.chat",
+ "service": "ai.enric.chat.api",
+ "tags": [
+ "env:production"
+ ]
+ }]'
client:
image: nginx:1.27.0-alpine
- container_name: LibreChat-NGINX
+ container_name: ai.enric.chat.client
ports:
- 80:80
- - 443:443
depends_on:
- api
restart: always
volumes:
- ./client/nginx.conf:/etc/nginx/conf.d/default.conf
+ labels:
+ com.datadoghq.ad.logs: '[{
+ "source": "ai.enric.chat",
+ "service": "ai.enric.chat.client",
+ "tags": [
+ "env:production"
+ ]
+ }]'
mongodb:
- container_name: chat-mongodb
+ container_name: ai.enric.chat.mongodb
# ports: # Uncomment this to access mongodb from outside docker, not safe in deployment
# - 27018:27017
image: mongo
@@ -51,12 +64,20 @@ services:
volumes:
- ./data-node:/data/db
command: mongod --noauth
+ labels:
+ com.datadoghq.ad.logs: '[{
+ "source": "ai.enric.chat",
+ "service": "ai.enric.chat.mongodb",
+ "tags": [
+ "env:production"
+ ]
+ }]'
meilisearch:
- container_name: chat-meilisearch
+ container_name: ai.enric.chat.meilisearch
image: getmeili/meilisearch:v1.7.3
- restart: always
# ports: # Uncomment this to access meilisearch from outside docker
# - 7700:7700 # if exposing these ports, make sure your master key is not the default value
+ restart: always
env_file:
- .env
environment:
@@ -64,25 +85,82 @@ services:
- MEILI_NO_ANALYTICS=true
volumes:
- ./meili_data_v1.7:/meili_data
+ labels:
+ com.datadoghq.ad.logs: '[{
+ "source": "ai.enric.chat",
+ "service": "ai.enric.chat.meilisearch",
+ "tags": [
+ "env:production"
+ ]
+ }]'
vectordb:
+ container_name: ai.enric.chat.pgvector
image: ankane/pgvector:latest
- environment:
- POSTGRES_DB: mydatabase
- POSTGRES_USER: myuser
- POSTGRES_PASSWORD: mypassword
restart: always
+ env_file:
+ - .env
+ environment:
+ - POSTGRES_DB
+ - POSTGRES_USER
+ - POSTGRES_PASSWORD
volumes:
- pgdata2:/var/lib/postgresql/data
+ labels:
+ com.datadoghq.ad.logs: '[{
+ "source": "ai.enric.chat",
+ "service": "ai.enric.chat.pgvector",
+ "tags": [
+ "env:production"
+ ]
+ }]'
+ # ports:
+ # - 5432:5432
rag_api:
+ container_name: ai.enric.chat.rag-api
image: ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest
+ restart: always
+ env_file:
+ - .env
environment:
- DB_HOST=vectordb
+ - DB_PORT=${DB_PORT:-5432}
- RAG_PORT=${RAG_PORT:-8000}
- restart: always
depends_on:
- vectordb
+ labels:
+ com.datadoghq.ad.logs: '[{
+ "source": "ai.enric.chat",
+ "service": "ai.enric.chat.ragapi",
+ "tags": [
+ "env:production"
+ ]
+ }]'
+ # ports:
+ # - 8000:8000
+ datadog:
+ container_name: datadog-agent
+ image: gcr.io/datadoghq/agent:latest
+ environment:
+ - DD_LOGS_ENABLED=true
+ - DD_API_KEY
+ - DD_SITE
+ - DD_APM_ENABLED=${DD_APM_ENABLED:-true}
+ - DD_APM_NON_LOCAL_TRAFFIC=${DD_APM_NON_LOCAL_TRAFFIC:-true}
+ - DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL=${DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL:-true}
+ - DD_CONTAINER_EXCLUDE="name:agent"
+ restart: always
+ depends_on:
+ - rag_api
env_file:
- .env
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - /proc/:/host/proc/:ro
+ - /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
+ - /opt/datadog-agent/run:/opt/datadog-agent/run:rw
+ - ./logs:/app/api/logs
+ security_opt:
+ - apparmor:unconfined
volumes:
pgdata2:
diff --git a/docker-compose.override.yml.example b/docker-compose.override.yml.example
index 3799341ce69..0b681d42d45 100644
--- a/docker-compose.override.yml.example
+++ b/docker-compose.override.yml.example
@@ -17,7 +17,7 @@
# - type: bind
# source: ./librechat.yaml
# target: /app/librechat.yaml
-# image: ghcr.io/danny-avila/librechat:latest
+# image: ghcr.io/enricai/librechat:latest
# ---------------------------------------------------
@@ -39,19 +39,19 @@
# # BUILD FROM LATEST IMAGE
# api:
-# image: ghcr.io/danny-avila/librechat-dev:latest
+# image: ghcr.io/enricai/librechat-dev:latest
# # BUILD FROM LATEST IMAGE (NUMBERED RELEASE)
# api:
-# image: ghcr.io/danny-avila/librechat:latest
+# image: ghcr.io/enricai/librechat:latest
# # BUILD FROM LATEST API IMAGE
# api:
-# image: ghcr.io/danny-avila/librechat-dev-api:latest
+# image: ghcr.io/enricai/librechat-dev-api:latest
# # BUILD FROM LATEST API IMAGE (NUMBERED RELEASE)
# api:
-# image: ghcr.io/danny-avila/librechat-api:latest
+# image: ghcr.io/enricai/librechat-api:latest
# # ADD MONGO-EXPRESS
# mongo-express:
diff --git a/docker-compose.yml b/docker-compose.yml
index 1e2221dcb72..ff25a73d788 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -9,7 +9,7 @@ services:
depends_on:
- mongodb
- rag_api
- image: ghcr.io/danny-avila/librechat-dev:latest
+ image: ghcr.io/enricai/librechat-dev:latest
restart: always
user: "${UID}:${GID}"
extra_hosts:
diff --git a/package-lock.json b/package-lock.json
index 78f952566b7..35e32473ef0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -87,7 +87,7 @@
"meilisearch": "^0.38.0",
"mime": "^3.0.0",
"module-alias": "^2.2.3",
- "mongoose": "^8.8.3",
+ "mongoose": "^8.9.5",
"multer": "^1.4.5-lts.1",
"nanoid": "^3.3.7",
"nodejs-gpt": "^1.37.4",
@@ -687,14 +687,6 @@
"@types/webidl-conversions": "*"
}
},
- "api/node_modules/bson": {
- "version": "6.10.1",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz",
- "integrity": "sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==",
- "engines": {
- "node": ">=16.20.1"
- }
- },
"api/node_modules/cookie-parser": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
@@ -730,14 +722,6 @@
"node": ">= 0.6"
}
},
- "api/node_modules/kareem": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
- "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
- "engines": {
- "node": ">=12.0.0"
- }
- },
"api/node_modules/mongodb": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz",
@@ -889,11 +873,6 @@
}
}
},
- "api/node_modules/sift": {
- "version": "17.1.3",
- "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
- "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ=="
- },
"api/node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -10312,9 +10291,9 @@
}
},
"node_modules/@mongodb-js/saslprep": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz",
- "integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==",
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
+ "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==",
"dependencies": {
"sparse-bitfield": "^3.0.3"
}
@@ -16479,13 +16458,11 @@
}
},
"node_modules/bson": {
- "version": "5.5.1",
- "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz",
- "integrity": "sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==",
- "optional": true,
- "peer": true,
+ "version": "6.10.1",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz",
+ "integrity": "sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==",
"engines": {
- "node": ">=14.20.1"
+ "node": ">=16.20.1"
}
},
"node_modules/buffer": {
@@ -23944,6 +23921,14 @@
"safe-buffer": "^5.0.1"
}
},
+ "node_modules/kareem": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
+ "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/katex": {
"version": "0.16.10",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz",
@@ -26956,28 +26941,26 @@
}
},
"node_modules/mongodb": {
- "version": "5.9.2",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz",
- "integrity": "sha512-H60HecKO4Bc+7dhOv4sJlgvenK4fQNqqUIlXxZYQNbfEWSALGAwGoyJd/0Qwk4TttFXUOHJ2ZJQe/52ScaUwtQ==",
- "optional": true,
- "peer": true,
+ "version": "6.12.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.12.0.tgz",
+ "integrity": "sha512-RM7AHlvYfS7jv7+BXund/kR64DryVI+cHbVAy9P61fnb1RcWZqOW1/Wj2YhqMCx+MuYhqTRGv7AwHBzmsCKBfA==",
+ "devOptional": true,
"dependencies": {
- "bson": "^5.5.0",
- "mongodb-connection-string-url": "^2.6.0",
- "socks": "^2.7.1"
+ "@mongodb-js/saslprep": "^1.1.9",
+ "bson": "^6.10.1",
+ "mongodb-connection-string-url": "^3.0.0"
},
"engines": {
- "node": ">=14.20.1"
- },
- "optionalDependencies": {
- "@mongodb-js/saslprep": "^1.1.0"
+ "node": ">=16.20.1"
},
"peerDependencies": {
"@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.0.0",
- "kerberos": "^1.0.0 || ^2.0.0",
- "mongodb-client-encryption": ">=2.3.0 <3",
- "snappy": "^7.2.2"
+ "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
+ "gcp-metadata": "^5.2.0",
+ "kerberos": "^2.0.1",
+ "mongodb-client-encryption": ">=6.0.0 <7",
+ "snappy": "^7.2.2",
+ "socks": "^2.7.1"
},
"peerDependenciesMeta": {
"@aws-sdk/credential-providers": {
@@ -26986,6 +26969,9 @@
"@mongodb-js/zstd": {
"optional": true
},
+ "gcp-metadata": {
+ "optional": true
+ },
"kerberos": {
"optional": true
},
@@ -26994,6 +26980,9 @@
},
"snappy": {
"optional": true
+ },
+ "socks": {
+ "optional": true
}
}
},
@@ -27043,15 +27032,6 @@
"node": ">=16.20.1"
}
},
- "node_modules/mongodb-memory-server-core/node_modules/@types/whatwg-url": {
- "version": "11.0.5",
- "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
- "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
- "dev": true,
- "dependencies": {
- "@types/webidl-conversions": "*"
- }
- },
"node_modules/mongodb-memory-server-core/node_modules/agent-base": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
@@ -27064,15 +27044,6 @@
"node": ">= 14"
}
},
- "node_modules/mongodb-memory-server-core/node_modules/bson": {
- "version": "6.8.0",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz",
- "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==",
- "dev": true,
- "engines": {
- "node": ">=16.20.1"
- }
- },
"node_modules/mongodb-memory-server-core/node_modules/https-proxy-agent": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
@@ -27086,85 +27057,48 @@
"node": ">= 14"
}
},
- "node_modules/mongodb-memory-server-core/node_modules/mongodb": {
- "version": "6.8.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz",
- "integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==",
- "dev": true,
+ "node_modules/mongodb/node_modules/@types/whatwg-url": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
+ "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
+ "devOptional": true,
"dependencies": {
- "@mongodb-js/saslprep": "^1.1.5",
- "bson": "^6.7.0",
- "mongodb-connection-string-url": "^3.0.0"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "peerDependencies": {
- "@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.1.0",
- "gcp-metadata": "^5.2.0",
- "kerberos": "^2.0.1",
- "mongodb-client-encryption": ">=6.0.0 <7",
- "snappy": "^7.2.2",
- "socks": "^2.7.1"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-providers": {
- "optional": true
- },
- "@mongodb-js/zstd": {
- "optional": true
- },
- "gcp-metadata": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "snappy": {
- "optional": true
- },
- "socks": {
- "optional": true
- }
+ "@types/webidl-conversions": "*"
}
},
- "node_modules/mongodb-memory-server-core/node_modules/mongodb-connection-string-url": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz",
- "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==",
- "dev": true,
+ "node_modules/mongodb/node_modules/mongodb-connection-string-url": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
+ "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
+ "devOptional": true,
"dependencies": {
"@types/whatwg-url": "^11.0.2",
- "whatwg-url": "^13.0.0"
+ "whatwg-url": "^14.1.0 || ^13.0.0"
}
},
- "node_modules/mongodb-memory-server-core/node_modules/tr46": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
- "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
- "dev": true,
+ "node_modules/mongodb/node_modules/tr46": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
+ "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
+ "devOptional": true,
"dependencies": {
- "punycode": "^2.3.0"
+ "punycode": "^2.3.1"
},
"engines": {
- "node": ">=14"
+ "node": ">=18"
}
},
- "node_modules/mongodb-memory-server-core/node_modules/whatwg-url": {
- "version": "13.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz",
- "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==",
- "dev": true,
+ "node_modules/mongodb/node_modules/whatwg-url": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz",
+ "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==",
+ "devOptional": true,
"dependencies": {
- "tr46": "^4.1.1",
+ "tr46": "^5.0.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
}
},
"node_modules/moo": {
@@ -32505,6 +32439,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sift": {
+ "version": "17.1.3",
+ "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
+ "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ=="
+ },
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
diff --git a/package.json b/package.json
index a2d8d3b4adc..aebc03ef917 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"update:sudo": "node config/update.js --sudo",
"update:deployed": "node config/deployed-update.js",
"rebase:deployed": "node config/deployed-update.js --rebase",
+ "build:deployed": "docker-compose -f ./deploy-compose.yml build",
"start:deployed": "docker-compose -f ./deploy-compose.yml up -d",
"stop:deployed": "docker-compose -f ./deploy-compose.yml down",
"upgrade": "node config/upgrade.js",
@@ -69,12 +70,12 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/danny-avila/LibreChat.git"
+ "url": "git+https://github.com/enricai/LibreChat.git"
},
"author": "",
"license": "ISC",
"bugs": {
- "url": "https://github.com/danny-avila/LibreChat/issues"
+ "url": "https://github.com/enricai/LibreChat/issues"
},
"homepage": "https://librechat.ai/",
"devDependencies": {
diff --git a/packages/data-provider/package.json b/packages/data-provider/package.json
index c38049f031a..15cd19b51a8 100644
--- a/packages/data-provider/package.json
+++ b/packages/data-provider/package.json
@@ -30,12 +30,12 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/danny-avila/LibreChat.git"
+ "url": "git+https://github.com/enricai/LibreChat.git"
},
"author": "",
"license": "ISC",
"bugs": {
- "url": "https://github.com/danny-avila/LibreChat/issues"
+ "url": "https://github.com/enricai/LibreChat/issues"
},
"homepage": "https://librechat.ai",
"dependencies": {
diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts
index e879dadf487..c17ea3be09e 100644
--- a/packages/data-provider/src/config.ts
+++ b/packages/data-provider/src/config.ts
@@ -151,7 +151,7 @@ export enum AgentCapabilities {
export const defaultAssistantsVersion = {
[EModelEndpoint.assistants]: 2,
- [EModelEndpoint.azureAssistants]: 1,
+ [EModelEndpoint.azureAssistants]: 2,
};
export const baseEndpointSchema = z.object({
@@ -710,7 +710,7 @@ export const EndpointURLs: { [key in EModelEndpoint]: string } = {
[EModelEndpoint.gptPlugins]: `/api/ask/${EModelEndpoint.gptPlugins}`,
[EModelEndpoint.azureOpenAI]: `/api/ask/${EModelEndpoint.azureOpenAI}`,
[EModelEndpoint.chatGPTBrowser]: `/api/ask/${EModelEndpoint.chatGPTBrowser}`,
- [EModelEndpoint.azureAssistants]: '/api/assistants/v1/chat',
+ [EModelEndpoint.azureAssistants]: '/api/assistants/v2/chat',
[EModelEndpoint.assistants]: '/api/assistants/v2/chat',
[EModelEndpoint.agents]: `/api/${EModelEndpoint.agents}/chat`,
[EModelEndpoint.bedrock]: `/api/${EModelEndpoint.bedrock}/chat`,