From cd7f3a51e119ecf386b61ade984fa0c30de54a6a Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 5 Apr 2024 15:19:41 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=A0=20feat:=20Cohere=20support=20as=20?= =?UTF-8?q?Custom=20Endpoint=20(#2328)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: bump cohere-ai, fix firebase vulnerabilities by going down versions * feat: cohere rates and context windows * feat(createCoherePayload): transform openai payload for cohere compatibility * feat: cohere backend support * refactor(UnknownIcon): optimize icon render and add cohere * docs: add cohere to Compatible AI Endpoints * Update ai_endpoints.md --- api/app/clients/BaseClient.js | 2 +- api/app/clients/ChatGPTClient.js | 40 +- api/app/clients/OpenAIClient.js | 37 +- api/app/clients/llm/createCoherePayload.js | 85 ++ api/app/clients/llm/index.js | 2 + api/app/clients/prompts/titlePrompts.js | 5 +- api/models/tx.js | 6 + api/package.json | 4 +- api/typedefs.js | 65 + api/utils/extractBaseURL.js | 6 + api/utils/tokens.js | 15 +- client/public/assets/cohere.png | Bin 0 -> 26469 bytes client/src/common/types.ts | 7 + .../Chat/Menus/Endpoints/UnknownIcon.tsx | 123 +- docs/install/configuration/ai_endpoints.md | 33 + package-lock.json | 1170 +++++++++-------- packages/data-provider/package.json | 2 +- packages/data-provider/src/config.ts | 27 + 18 files changed, 1007 insertions(+), 622 deletions(-) create mode 100644 api/app/clients/llm/createCoherePayload.js create mode 100644 client/public/assets/cohere.png diff --git a/api/app/clients/BaseClient.js b/api/app/clients/BaseClient.js index 53b2e1031..f7ed3b9cf 100644 --- a/api/app/clients/BaseClient.js +++ b/api/app/clients/BaseClient.js @@ -23,7 +23,7 @@ class BaseClient { throw new Error('Method \'setOptions\' must be implemented.'); } - getCompletion() { + async getCompletion() { throw new Error('Method \'getCompletion\' must be implemented.'); } diff --git a/api/app/clients/ChatGPTClient.js b/api/app/clients/ChatGPTClient.js index bac7849a1..d21884951 100644 --- a/api/app/clients/ChatGPTClient.js +++ b/api/app/clients/ChatGPTClient.js @@ -3,10 +3,13 @@ const crypto = require('crypto'); const { EModelEndpoint, resolveHeaders, + CohereConstants, mapModelToAzureConfig, } = require('librechat-data-provider'); +const { CohereClient } = require('cohere-ai'); const { encoding_for_model: encodingForModel, get_encoding: getEncoding } = require('tiktoken'); const { fetchEventSource } = require('@waylaidwanderer/fetch-event-source'); +const { createCoherePayload } = require('./llm'); const { Agent, ProxyAgent } = require('undici'); const BaseClient = require('./BaseClient'); const { logger } = require('~/config'); @@ -147,7 +150,8 @@ class ChatGPTClient extends BaseClient { return tokenizer; } - async getCompletion(input, onProgress, abortController = null) { + /** @type {getCompletion} */ + async getCompletion(input, onProgress, onTokenProgress, abortController = null) { if (!abortController) { abortController = new AbortController(); } @@ -305,6 +309,11 @@ class ChatGPTClient extends BaseClient { }); } + if (baseURL.startsWith(CohereConstants.API_URL)) { + const payload = createCoherePayload({ modelOptions }); + return await this.cohereChatCompletion({ payload, onTokenProgress }); + } + if (baseURL.includes('v1') && !baseURL.includes('/completions') && !this.isChatCompletion) { baseURL = baseURL.split('v1')[0] + 'v1/completions'; } else if ( @@ -408,6 +417,35 @@ class ChatGPTClient extends BaseClient { return response.json(); } + /** @type {cohereChatCompletion} */ + async cohereChatCompletion({ payload, onTokenProgress }) { + const cohere = new CohereClient({ + token: this.apiKey, + environment: this.completionsUrl, + }); + + if (!payload.stream) { + const chatResponse = await cohere.chat(payload); + return chatResponse.text; + } + + const chatStream = await cohere.chatStream(payload); + let reply = ''; + for await (const message of chatStream) { + if (!message) { + continue; + } + + if (message.eventType === 'text-generation' && message.text) { + onTokenProgress(message.text); + } else if (message.eventType === 'stream-end' && message.response) { + reply = message.response.text; + } + } + + return reply; + } + async generateTitle(userMessage, botMessage) { const instructionsPayload = { role: 'system', diff --git a/api/app/clients/OpenAIClient.js b/api/app/clients/OpenAIClient.js index ef6868254..9be04105c 100644 --- a/api/app/clients/OpenAIClient.js +++ b/api/app/clients/OpenAIClient.js @@ -5,6 +5,7 @@ const { EModelEndpoint, resolveHeaders, ImageDetailCost, + CohereConstants, getResponseSender, validateVisionModel, mapModelToAzureConfig, @@ -16,7 +17,13 @@ const { getModelMaxTokens, genAzureChatCompletion, } = require('~/utils'); -const { truncateText, formatMessage, createContextHandlers, CUT_OFF_PROMPT } = require('./prompts'); +const { + truncateText, + formatMessage, + createContextHandlers, + CUT_OFF_PROMPT, + titleInstruction, +} = require('./prompts'); const { encodeAndFormat } = require('~/server/services/Files/images/encode'); const { handleOpenAIErrors } = require('./tools/util'); const spendTokens = require('~/models/spendTokens'); @@ -39,7 +46,10 @@ class OpenAIClient extends BaseClient { super(apiKey, options); this.ChatGPTClient = new ChatGPTClient(); this.buildPrompt = this.ChatGPTClient.buildPrompt.bind(this); + /** @type {getCompletion} */ this.getCompletion = this.ChatGPTClient.getCompletion.bind(this); + /** @type {cohereChatCompletion} */ + this.cohereChatCompletion = this.ChatGPTClient.cohereChatCompletion.bind(this); this.contextStrategy = options.contextStrategy ? options.contextStrategy.toLowerCase() : 'discard'; @@ -48,6 +58,9 @@ class OpenAIClient extends BaseClient { this.azure = options.azure || false; this.setOptions(options); this.metadata = {}; + + /** @type {string | undefined} - The API Completions URL */ + this.completionsUrl; } // TODO: PluginsClient calls this 3x, unneeded @@ -533,6 +546,7 @@ class OpenAIClient extends BaseClient { return result; } + /** @type {sendCompletion} */ async sendCompletion(payload, opts = {}) { let reply = ''; let result = null; @@ -541,7 +555,7 @@ class OpenAIClient extends BaseClient { const invalidBaseUrl = this.completionsUrl && extractBaseURL(this.completionsUrl) === null; const useOldMethod = !!(invalidBaseUrl || !this.isChatCompletion || typeof Bun !== 'undefined'); if (typeof opts.onProgress === 'function' && useOldMethod) { - await this.getCompletion( + const completionResult = await this.getCompletion( payload, (progressMessage) => { if (progressMessage === '[DONE]') { @@ -574,8 +588,13 @@ class OpenAIClient extends BaseClient { opts.onProgress(token); reply += token; }, + opts.onProgress, opts.abortController || new AbortController(), ); + + if (completionResult && typeof completionResult === 'string') { + reply = completionResult; + } } else if (typeof opts.onProgress === 'function' || this.options.useChatCompletion) { reply = await this.chatCompletion({ payload, @@ -586,9 +605,14 @@ class OpenAIClient extends BaseClient { result = await this.getCompletion( payload, null, + opts.onProgress, opts.abortController || new AbortController(), ); + if (result && typeof result === 'string') { + return result.trim(); + } + logger.debug('[OpenAIClient] sendCompletion: result', result); if (this.isChatCompletion) { @@ -760,8 +784,7 @@ class OpenAIClient extends BaseClient { const instructionsPayload = [ { role: 'system', - content: `Detect user language and write in the same language an extremely concise title for this conversation, which you must accurately detect. -Write in the detected language. Title in 5 Words or Less. No Punctuation or Quotation. Do not mention the language. All first letters of every word should be capitalized and write the title in User Language only. + content: `Please generate ${titleInstruction} ${convo} @@ -770,8 +793,12 @@ ${convo} ]; try { + let useChatCompletion = true; + if (CohereConstants.API_URL) { + useChatCompletion = false; + } title = ( - await this.sendPayload(instructionsPayload, { modelOptions, useChatCompletion: true }) + await this.sendPayload(instructionsPayload, { modelOptions, useChatCompletion }) ).replaceAll('"', ''); } catch (e) { logger.error( diff --git a/api/app/clients/llm/createCoherePayload.js b/api/app/clients/llm/createCoherePayload.js new file mode 100644 index 000000000..d399f7055 --- /dev/null +++ b/api/app/clients/llm/createCoherePayload.js @@ -0,0 +1,85 @@ +const { CohereConstants } = require('librechat-data-provider'); +const { titleInstruction } = require('../prompts/titlePrompts'); + +// Mapping OpenAI roles to Cohere roles +const roleMap = { + user: CohereConstants.ROLE_USER, + assistant: CohereConstants.ROLE_CHATBOT, + system: CohereConstants.ROLE_SYSTEM, // Recognize and map the system role explicitly +}; + +/** + * Adjusts an OpenAI ChatCompletionPayload to conform with Cohere's expected chat payload format. + * Now includes handling for "system" roles explicitly mentioned. + * + * @param {Object} options - Object containing the model options. + * @param {ChatCompletionPayload} options.modelOptions - The OpenAI model payload options. + * @returns {CohereChatStreamRequest} Cohere-compatible chat API payload. + */ +function createCoherePayload({ modelOptions }) { + /** @type {string | undefined} */ + let preamble; + let latestUserMessageContent = ''; + const { + stream, + stop, + top_p, + temperature, + frequency_penalty, + presence_penalty, + max_tokens, + messages, + model, + ...rest + } = modelOptions; + + // Filter out the latest user message and transform remaining messages to Cohere's chat_history format + let chatHistory = messages.reduce((acc, message, index, arr) => { + const isLastUserMessage = index === arr.length - 1 && message.role === 'user'; + + const messageContent = + typeof message.content === 'string' + ? message.content + : message.content.map((part) => (part.type === 'text' ? part.text : '')).join(' '); + + if (isLastUserMessage) { + latestUserMessageContent = messageContent; + } else { + acc.push({ + role: roleMap[message.role] || CohereConstants.ROLE_USER, + message: messageContent, + }); + } + + return acc; + }, []); + + if ( + chatHistory.length === 1 && + chatHistory[0].role === CohereConstants.ROLE_SYSTEM && + !latestUserMessageContent.length + ) { + const message = chatHistory[0].message; + latestUserMessageContent = message.includes(titleInstruction) + ? CohereConstants.TITLE_MESSAGE + : '.'; + preamble = message; + } + + return { + message: latestUserMessageContent, + model: model, + chat_history: chatHistory, + stream: stream ?? false, + temperature: temperature, + frequency_penalty: frequency_penalty, + presence_penalty: presence_penalty, + max_tokens: max_tokens, + stop_sequences: stop, + preamble, + p: top_p, + ...rest, + }; +} + +module.exports = createCoherePayload; diff --git a/api/app/clients/llm/index.js b/api/app/clients/llm/index.js index 46478ade6..2e09bbb84 100644 --- a/api/app/clients/llm/index.js +++ b/api/app/clients/llm/index.js @@ -1,7 +1,9 @@ const createLLM = require('./createLLM'); const RunManager = require('./RunManager'); +const createCoherePayload = require('./createCoherePayload'); module.exports = { createLLM, RunManager, + createCoherePayload, }; diff --git a/api/app/clients/prompts/titlePrompts.js b/api/app/clients/prompts/titlePrompts.js index 3376af297..83d8909f3 100644 --- a/api/app/clients/prompts/titlePrompts.js +++ b/api/app/clients/prompts/titlePrompts.js @@ -27,6 +27,8 @@ ${convo}`, return titlePrompt; }; +const titleInstruction = + 'a concise, 5-word-or-less title for the conversation, using its same language, with no punctuation. Apply title case conventions appropriate for the language. For English, use AP Stylebook Title Case. Never directly mention the language name or the word "title"'; const titleFunctionPrompt = `In this environment you have access to a set of tools you can use to generate the conversation title. You may call them like this: @@ -51,7 +53,7 @@ Submit a brief title in the conversation's language, following the parameter des title string -A concise, 5-word-or-less title for the conversation, using its same language, with no punctuation. Apply title case conventions appropriate for the language. For English, use AP Stylebook Title Case. Never directly mention the language name or the word "title" +${titleInstruction} @@ -80,6 +82,7 @@ function parseTitleFromPrompt(prompt) { module.exports = { langPrompt, + titleInstruction, createTitlePrompt, titleFunctionPrompt, parseTitleFromPrompt, diff --git a/api/models/tx.js b/api/models/tx.js index 67bfa4d00..bc993290f 100644 --- a/api/models/tx.js +++ b/api/models/tx.js @@ -3,6 +3,7 @@ const defaultRate = 6; /** * Mapping of model token sizes to their respective multipliers for prompt and completion. + * The rates are 1 USD per 1M tokens. * @type {Object.} */ const tokenValues = { @@ -19,6 +20,11 @@ const tokenValues = { 'claude-2.1': { prompt: 8, completion: 24 }, 'claude-2': { prompt: 8, completion: 24 }, 'claude-': { prompt: 0.8, completion: 2.4 }, + 'command-r-plus': { prompt: 3, completion: 15 }, + 'command-r': { prompt: 0.5, completion: 1.5 }, + /* cohere doesn't have rates for the older command models, + so this was from https://artificialanalysis.ai/models/command-light/providers */ + command: { prompt: 0.38, completion: 0.38 }, }; /** diff --git a/api/package.json b/api/package.json index 5d8d1e56d..31df31f7c 100644 --- a/api/package.json +++ b/api/package.json @@ -42,7 +42,7 @@ "axios": "^1.3.4", "bcryptjs": "^2.4.3", "cheerio": "^1.0.0-rc.12", - "cohere-ai": "^6.0.0", + "cohere-ai": "^7.9.1", "connect-redis": "^7.1.0", "cookie": "^0.5.0", "cors": "^2.8.5", @@ -52,7 +52,7 @@ "express-rate-limit": "^6.9.0", "express-session": "^1.17.3", "file-type": "^18.7.0", - "firebase": "^10.8.0", + "firebase": "^10.6.0", "googleapis": "^126.0.1", "handlebars": "^4.7.7", "html": "^1.0.0", diff --git a/api/typedefs.js b/api/typedefs.js index c8ac7a5c8..e844e1eb9 100644 --- a/api/typedefs.js +++ b/api/typedefs.js @@ -44,6 +44,30 @@ * @memberof typedefs */ +/** + * @exports ChatCompletionPayload + * @typedef {import('openai').OpenAI.ChatCompletionCreateParams} ChatCompletionPayload + * @memberof typedefs + */ + +/** + * @exports ChatCompletionMessages + * @typedef {import('openai').OpenAI.ChatCompletionMessageParam} ChatCompletionMessages + * @memberof typedefs + */ + +/** + * @exports CohereChatStreamRequest + * @typedef {import('cohere-ai').Cohere.ChatStreamRequest} CohereChatStreamRequest + * @memberof typedefs + */ + +/** + * @exports CohereChatRequest + * @typedef {import('cohere-ai').Cohere.ChatRequest} CohereChatRequest + * @memberof typedefs + */ + /** * @exports OpenAIRequestOptions * @typedef {import('openai').OpenAI.RequestOptions} OpenAIRequestOptions @@ -1062,3 +1086,44 @@ * @method handleMessageEvent Handles events related to messages within the run. * @method messageCompleted Handles the completion of a message processing. */ + +/* Native app/client methods */ + +/** + * Accumulates tokens and sends them to the client for processing. + * @callback onTokenProgress + * @param {string} token - The current token generated by the model. + * @returns {Promise} + * @memberof typedefs + */ + +/** + * Main entrypoint for API completion calls + * @callback sendCompletion + * @param {Array | string} payload - The messages or prompt to send to the model + * @param {object} opts - Options for the completion + * @param {onTokenProgress} opts.onProgress - Callback function to handle token progress + * @param {AbortController} opts.abortController - AbortController instance + * @returns {Promise} + * @memberof typedefs + */ + +/** + * Legacy completion handler for OpenAI API. + * @callback getCompletion + * @param {Array | string} input - Array of messages or a single prompt string + * @param {(event: object | string) => Promise} onProgress - SSE progress handler + * @param {onTokenProgress} onTokenProgress - Token progress handler + * @param {AbortController} [abortController] - AbortController instance + * @returns {Promise} - Completion response + * @memberof typedefs + */ + +/** + * Cohere Stream handling. Note: abortController is not supported here. + * @callback cohereChatCompletion + * @param {object} params + * @param {CohereChatStreamRequest | CohereChatRequest} params.payload + * @param {onTokenProgress} params.onTokenProgress + * @memberof typedefs + */ diff --git a/api/utils/extractBaseURL.js b/api/utils/extractBaseURL.js index 78e62fd8a..09bbb5505 100644 --- a/api/utils/extractBaseURL.js +++ b/api/utils/extractBaseURL.js @@ -1,3 +1,5 @@ +const { CohereConstants } = require('librechat-data-provider'); + /** * Extracts a valid OpenAI baseURL from a given string, matching "url/v1," followed by an optional suffix. * The suffix can be one of several predefined values (e.g., 'openai', 'azure-openai', etc.), @@ -19,6 +21,10 @@ function extractBaseURL(url) { return undefined; } + if (url.startsWith(CohereConstants.API_URL)) { + return null; + } + if (!url.includes('/v1')) { return url; } diff --git a/api/utils/tokens.js b/api/utils/tokens.js index e79182450..c35674a5c 100644 --- a/api/utils/tokens.js +++ b/api/utils/tokens.js @@ -59,6 +59,15 @@ const openAIModels = { 'mistral-': 31990, // -10 from max }; +const cohereModels = { + 'command-light': 4086, // -10 from max + 'command-light-nightly': 8182, // -10 from max + command: 4086, // -10 from max + 'command-nightly': 8182, // -10 from max + 'command-r': 127500, // -500 from max + 'command-r-plus:': 127500, // -500 from max +}; + const googleModels = { /* Max I/O is combined so we subtract the amount from max response tokens for actual total */ gemini: 32750, // -10 from max @@ -83,11 +92,13 @@ const anthropicModels = { 'claude-3-opus': 200000, }; +const aggregateModels = { ...openAIModels, ...googleModels, ...anthropicModels, ...cohereModels }; + // Order is important here: by model series and context size (gpt-4 then gpt-3, ascending) const maxTokensMap = { [EModelEndpoint.azureOpenAI]: openAIModels, - [EModelEndpoint.openAI]: { ...openAIModels, ...googleModels, ...anthropicModels }, - [EModelEndpoint.custom]: { ...openAIModels, ...googleModels, ...anthropicModels }, + [EModelEndpoint.openAI]: aggregateModels, + [EModelEndpoint.custom]: aggregateModels, [EModelEndpoint.google]: googleModels, [EModelEndpoint.anthropic]: anthropicModels, }; diff --git a/client/public/assets/cohere.png b/client/public/assets/cohere.png new file mode 100644 index 0000000000000000000000000000000000000000..3da0b8373718dae770a167a7bf8bdfaeff6d6074 GIT binary patch literal 26469 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 = (value: T | ((currentValue: T) => T)) => void; export type LastSelectedModels = Record; +export enum IconContext { + landing = 'landing', + menuItem = 'menu-item', + nav = 'nav', + message = 'message', +} + export type NavLink = { title: string; label?: string; diff --git a/client/src/components/Chat/Menus/Endpoints/UnknownIcon.tsx b/client/src/components/Chat/Menus/Endpoints/UnknownIcon.tsx index eed21c57a..0c7662bac 100644 --- a/client/src/components/Chat/Menus/Endpoints/UnknownIcon.tsx +++ b/client/src/components/Chat/Menus/Endpoints/UnknownIcon.tsx @@ -1,5 +1,44 @@ import { EModelEndpoint, KnownEndpoints } from 'librechat-data-provider'; import { CustomMinimalIcon } from '~/components/svg'; +import { IconContext } from '~/common'; + +const knownEndpointAssets = { + [KnownEndpoints.mistral]: '/assets/mistral.png', + [KnownEndpoints.openrouter]: '/assets/openrouter.png', + [KnownEndpoints.groq]: '/assets/groq.png', + [KnownEndpoints.shuttleai]: '/assets/shuttleai.png', + [KnownEndpoints.anyscale]: '/assets/anyscale.png', + [KnownEndpoints.fireworks]: '/assets/fireworks.png', + [KnownEndpoints.ollama]: '/assets/ollama.png', + [KnownEndpoints.perplexity]: '/assets/perplexity.png', + [KnownEndpoints['together.ai']]: '/assets/together.png', + [KnownEndpoints.cohere]: '/assets/cohere.png', +}; + +const knownEndpointClasses = { + [KnownEndpoints.cohere]: { + [IconContext.landing]: 'p-2', + }, +}; + +const getKnownClass = ({ + currentEndpoint, + context = '', + className, +}: { + currentEndpoint: string; + context?: string; + className: string; +}) => { + if (currentEndpoint === KnownEndpoints.openrouter) { + return className; + } + + const match = knownEndpointClasses[currentEndpoint]?.[context]; + const defaultClass = context === IconContext.landing ? '' : className; + + return match ?? defaultClass; +}; export default function UnknownIcon({ className = '', @@ -20,73 +59,23 @@ export default function UnknownIcon({ if (iconURL) { return {`${endpoint}; - } else if (currentEndpoint === KnownEndpoints.mistral) { - return ( - Mistral AI Icon - ); - } else if (currentEndpoint === KnownEndpoints.openrouter) { - return OpenRouter Icon; - } else if (currentEndpoint === KnownEndpoints.groq) { - return ( - Groq Cloud Icon - ); - } else if (currentEndpoint === KnownEndpoints.shuttleai) { - return ( - ShuttleAI Icon - ); - } else if (currentEndpoint === KnownEndpoints.anyscale) { - return ( - Anyscale Icon - ); - } else if (currentEndpoint === KnownEndpoints.fireworks) { - return ( - Fireworks Icon - ); - } else if (currentEndpoint === KnownEndpoints.ollama) { - return ( - Ollama Icon - ); - } else if (currentEndpoint === KnownEndpoints.perplexity) { - return ( - Perplexity Icon - ); - } else if (currentEndpoint === KnownEndpoints['together.ai']) { - return ( - together.ai Icon - ); } - return ; + const assetPath = knownEndpointAssets[currentEndpoint]; + + if (!assetPath) { + return ; + } + + return ( + {`${currentEndpoint} + ); } diff --git a/docs/install/configuration/ai_endpoints.md b/docs/install/configuration/ai_endpoints.md index b6beb52fa..d6142c7f9 100644 --- a/docs/install/configuration/ai_endpoints.md +++ b/docs/install/configuration/ai_endpoints.md @@ -14,6 +14,39 @@ In all of the examples, arbitrary environment variable names are defined but you Some of the endpoints are marked as **Known,** which means they might have special handling and/or an icon already provided in the app for you. +## Cohere +> Cohere API key: [dashboard.cohere.com](https://dashboard.cohere.com/) + +**Notes:** + +- **Known:** icon provided. +- Experimental: does not follow OpenAI-spec, uses a new method for endpoint compatibility, shares some similarities and parameters. +- For a full list of Cohere-specific parameters, see the [Cohere API documentation](https://docs.cohere.com/reference/chat). +- Note: The following parameters are recognized between OpenAI and Cohere. Most are removed in the example config below to prefer Cohere's default settings: + - `stop`: mapped to `stop_sequences` + - `top_p`: mapped to `p`, different min/max values + - `frequency_penalty`: different min/max values + - `presence_penalty`: different min/max values + - `model`: shared, included by default. + - `stream`: shared, included by default. + - `max_tokens`: shared, not included by default. + + +```yaml + - name: "cohere" + apiKey: "${COHERE_API_KEY}" + baseURL: "https://api.cohere.ai/v1" + models: + default: ["command-r","command-r-plus","command-light","command-light-nightly","command","command-nightly"] + fetch: false + modelDisplayLabel: "cohere" + titleModel: "command" + dropParams: ["stop", "user", "frequency_penalty", "presence_penalty", "temperature", "top_p"] +``` + +![image](https://github.com/danny-avila/LibreChat/assets/110412045/03549e00-243c-4539-ac9a-0d782af7cd6c) + + ## Groq > groq API key: [wow.groq.com](https://wow.groq.com/) diff --git a/package-lock.json b/package-lock.json index 9e489a5a6..32cc493fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "axios": "^1.3.4", "bcryptjs": "^2.4.3", "cheerio": "^1.0.0-rc.12", - "cohere-ai": "^6.0.0", + "cohere-ai": "^7.9.1", "connect-redis": "^7.1.0", "cookie": "^0.5.0", "cors": "^2.8.5", @@ -60,7 +60,7 @@ "express-rate-limit": "^6.9.0", "express-session": "^1.17.3", "file-type": "^18.7.0", - "firebase": "^10.8.0", + "firebase": "^10.6.0", "googleapis": "^126.0.1", "handlebars": "^4.7.7", "html": "^1.0.0", @@ -106,6 +106,500 @@ "supertest": "^6.3.3" } }, + "api/node_modules/@firebase/analytics": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.0.tgz", + "integrity": "sha512-Locv8gAqx0e+GX/0SI3dzmBY5e9kjVDtD+3zCFLJ0tH2hJwuCAiL+5WkHuxKj92rqQj/rvkBUCfA1ewlX2hehg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/analytics-compat": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.6.tgz", + "integrity": "sha512-4MqpVLFkGK7NJf/5wPEEP7ePBJatwYpyjgJ+wQHQGHfzaCDgntOnl9rL2vbVGGKCnRqWtZDIWhctB86UWXaX2Q==", + "dependencies": { + "@firebase/analytics": "0.10.0", + "@firebase/analytics-types": "0.8.0", + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/analytics-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz", + "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==" + }, + "api/node_modules/@firebase/app": { + "version": "0.9.23", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.23.tgz", + "integrity": "sha512-CA5pQ88We3FhyuesGKn1thaPBsJSGJGm6AlFToOmEJagWqBeDoNJqBkry/BsHnCs9xeYWWIprKxvuFmAFkdqoA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "idb": "7.1.1", + "tslib": "^2.1.0" + } + }, + "api/node_modules/@firebase/app-check": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.0.tgz", + "integrity": "sha512-dRDnhkcaC2FspMiRK/Vbp+PfsOAEP6ZElGm9iGFJ9fDqHoPs0HOPn7dwpJ51lCFi1+2/7n5pRPGhqF/F03I97g==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/app-check-compat": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.7.tgz", + "integrity": "sha512-cW682AxsyP1G+Z0/P7pO/WT2CzYlNxoNe5QejVarW2o5ZxeWSSPAiVEwpEpQR/bUlUmdeWThYTMvBWaopdBsqw==", + "dependencies": { + "@firebase/app-check": "0.8.0", + "@firebase/app-check-types": "0.5.0", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/app-check-interop-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", + "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" + }, + "api/node_modules/@firebase/app-check-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz", + "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==" + }, + "api/node_modules/@firebase/app-compat": { + "version": "0.2.23", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.23.tgz", + "integrity": "sha512-UCv0LEzcoqAgY+sLsau7aOZz0CJNLN2gESY68bHKmukNXEN6onLPxBKJzn68CsZZGcdiIEXwvrum1riWNPe9Gw==", + "dependencies": { + "@firebase/app": "0.9.23", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "api/node_modules/@firebase/app-types": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", + "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" + }, + "api/node_modules/@firebase/auth": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", + "integrity": "sha512-SfFXZCHDbY+7oSR52NSwx0U7LjYiA+N8imloxphCf3/F+MFty/+mhdjSXGtrJYd0Gbud/qcyedfn2XnWJeIB/g==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "api/node_modules/@firebase/auth-compat": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.9.tgz", + "integrity": "sha512-Fw03i7vduIciEBG4imLtA1duJbljgkfbxiBo/EuekcB+BnPxHp+e8OGMUfemPYeO7Munj6kUC9gr5DelsQkiNA==", + "dependencies": { + "@firebase/auth": "1.4.0", + "@firebase/auth-types": "0.12.0", + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/auth-interop-types": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", + "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" + }, + "api/node_modules/@firebase/auth-types": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", + "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "api/node_modules/@firebase/component": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "dependencies": { + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "api/node_modules/@firebase/database": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.1.tgz", + "integrity": "sha512-VAhF7gYwunW4Lw/+RQZvW8dlsf2r0YYqV9W0Gi2Mz8+0TGg1mBJWoUtsHfOr8kPJXhcLsC4eP/z3x6L/Fvjk/A==", + "dependencies": { + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "api/node_modules/@firebase/database-compat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.1.tgz", + "integrity": "sha512-ky82yLIboLxtAIWyW/52a6HLMVTzD2kpZlEilVDok73pNPLjkJYowj8iaIWK5nTy7+6Gxt7d00zfjL6zckGdXQ==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/database": "1.0.1", + "@firebase/database-types": "1.0.0", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "api/node_modules/@firebase/database-types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.0.tgz", + "integrity": "sha512-SjnXStoE0Q56HcFgNQ+9SsmJc0c8TqGARdI/T44KXy+Ets3r6x/ivhQozT66bMnCEjJRywYoxNurRTMlZF8VNg==", + "dependencies": { + "@firebase/app-types": "0.9.0", + "@firebase/util": "1.9.3" + } + }, + "api/node_modules/@firebase/firestore": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.3.2.tgz", + "integrity": "sha512-K4TwMbgArWw+XAEUYX/vtk+TVy9n1uLeJKSrQeb89lwfkfyFINGLPME6YleaS0ovD1ziLM5/0WgL1CR4s53fDg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "@firebase/webchannel-wrapper": "0.10.3", + "@grpc/grpc-js": "~1.9.0", + "@grpc/proto-loader": "^0.7.8", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10.10.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/firestore-compat": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.22.tgz", + "integrity": "sha512-M166UvFvRri0CK/+5N0MIeXJVxR6BsX0/96xFT506DxRPIFezLjLcvfddtyFgfe0CtyQWoxBXt060uWUg3d/sw==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/firestore": "4.3.2", + "@firebase/firestore-types": "3.0.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/firestore-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.0.tgz", + "integrity": "sha512-Meg4cIezHo9zLamw0ymFYBD4SMjLb+ZXIbuN7T7ddXN6MGoICmOTq3/ltdCGoDCS2u+H1XJs2u/cYp75jsX9Qw==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "api/node_modules/@firebase/functions": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.10.0.tgz", + "integrity": "sha512-2U+fMNxTYhtwSpkkR6WbBcuNMOVaI7MaH3cZ6UAeNfj7AgEwHwMIFLPpC13YNZhno219F0lfxzTAA0N62ndWzA==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.0", + "@firebase/auth-interop-types": "0.2.1", + "@firebase/component": "0.6.4", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/functions-compat": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.5.tgz", + "integrity": "sha512-uD4jwgwVqdWf6uc3NRKF8cSZ0JwGqSlyhPgackyUPe+GAtnERpS4+Vr66g0b3Gge0ezG4iyHo/EXW/Hjx7QhHw==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/functions": "0.10.0", + "@firebase/functions-types": "0.6.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/functions-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz", + "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==" + }, + "api/node_modules/@firebase/installations": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.4.tgz", + "integrity": "sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/installations-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.4.tgz", + "integrity": "sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/installations-types": "0.5.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/installations-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz", + "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==", + "peerDependencies": { + "@firebase/app-types": "0.x" + } + }, + "api/node_modules/@firebase/installations/node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + }, + "api/node_modules/@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "api/node_modules/@firebase/messaging": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.4.tgz", + "integrity": "sha512-6JLZct6zUaex4g7HI3QbzeUrg9xcnmDAPTWpkoMpd/GoSVWH98zDoWXMGrcvHeCAIsLpFMe4MPoZkJbrPhaASw==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/messaging-interop-types": "0.2.0", + "@firebase/util": "1.9.3", + "idb": "7.0.1", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/messaging-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.4.tgz", + "integrity": "sha512-lyFjeUhIsPRYDPNIkYX1LcZMpoVbBWXX4rPl7c/rqc7G+EUea7IEtSt4MxTvh6fDfPuzLn7+FZADfscC+tNMfg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/messaging": "0.12.4", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/messaging-interop-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", + "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==" + }, + "api/node_modules/@firebase/messaging/node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + }, + "api/node_modules/@firebase/performance": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.4.tgz", + "integrity": "sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/performance-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.4.tgz", + "integrity": "sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/performance": "0.6.4", + "@firebase/performance-types": "0.2.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/performance-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz", + "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==" + }, + "api/node_modules/@firebase/remote-config": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.4.tgz", + "integrity": "sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/installations": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/remote-config-compat": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.4.tgz", + "integrity": "sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/remote-config": "0.4.4", + "@firebase/remote-config-types": "0.3.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/remote-config-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz", + "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==" + }, + "api/node_modules/@firebase/storage": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.11.2.tgz", + "integrity": "sha512-CtvoFaBI4hGXlXbaCHf8humajkbXhs39Nbh6MbNxtwJiCqxPy9iH3D3CCfXAvP0QvAAwmJUTK3+z9a++Kc4nkA==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" + } + }, + "api/node_modules/@firebase/storage-compat": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.2.tgz", + "integrity": "sha512-wvsXlLa9DVOMQJckbDNhXKKxRNNewyUhhbXev3t8kSgoCotd1v3MmqhKKz93ePhDnhHnDs7bYHy+Qa8dRY6BXw==", + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/storage": "0.11.2", + "@firebase/storage-types": "0.8.0", + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "api/node_modules/@firebase/storage-types": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz", + "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "api/node_modules/@firebase/util": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "api/node_modules/@firebase/webchannel-wrapper": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.3.tgz", + "integrity": "sha512-+ZplYUN3HOpgCfgInqgdDAbkGGVzES1cs32JJpeqoh87SkRobGXElJx+1GZSaDqzFL+bYiX18qEcBK76mYs8uA==" + }, "api/node_modules/@types/node": { "version": "18.19.14", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.14.tgz", @@ -114,6 +608,58 @@ "undici-types": "~5.26.4" } }, + "api/node_modules/firebase": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.6.0.tgz", + "integrity": "sha512-bnYwHwZ6zB+dM6mGQPEXcFHtAT2WoVzG6H4SIR8HzURVGKJxBW+TqfP3qcJQjTZV3tDqDTo/XZkVmoU/SovV8A==", + "dependencies": { + "@firebase/analytics": "0.10.0", + "@firebase/analytics-compat": "0.2.6", + "@firebase/app": "0.9.23", + "@firebase/app-check": "0.8.0", + "@firebase/app-check-compat": "0.3.7", + "@firebase/app-compat": "0.2.23", + "@firebase/app-types": "0.9.0", + "@firebase/auth": "1.4.0", + "@firebase/auth-compat": "0.4.9", + "@firebase/database": "1.0.1", + "@firebase/database-compat": "1.0.1", + "@firebase/firestore": "4.3.2", + "@firebase/firestore-compat": "0.3.22", + "@firebase/functions": "0.10.0", + "@firebase/functions-compat": "0.3.5", + "@firebase/installations": "0.6.4", + "@firebase/installations-compat": "0.2.4", + "@firebase/messaging": "0.12.4", + "@firebase/messaging-compat": "0.2.4", + "@firebase/performance": "0.6.4", + "@firebase/performance-compat": "0.2.4", + "@firebase/remote-config": "0.4.4", + "@firebase/remote-config-compat": "0.2.4", + "@firebase/storage": "0.11.2", + "@firebase/storage-compat": "0.3.2", + "@firebase/util": "1.9.3" + } + }, + "api/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "api/node_modules/openai": { "version": "4.29.0", "resolved": "https://registry.npmjs.org/openai/-/openai-4.29.0.tgz", @@ -133,6 +679,25 @@ "openai": "bin/cli" } }, + "api/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "api/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "api/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "client": { "name": "@librechat/frontend", "version": "0.7.0", @@ -4859,491 +5424,6 @@ "fast-deep-equal": "^3.1.3" } }, - "node_modules/@firebase/analytics": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.1.tgz", - "integrity": "sha512-5mnH1aQa99J5lZMJwTNzIoRc4yGXHf+fOn+EoEWhCDA3XGPweGHcylCbqq+G1wVJmfILL57fohDMa8ftMZ+44g==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/analytics-compat": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.7.tgz", - "integrity": "sha512-17VCly4P0VFBDqaaal7m1nhyYQwsygtaTpSsnc51sFPRrr9XIYtnD8ficon9fneEGEoJQ2g7OtASvhwX9EbK8g==", - "dependencies": { - "@firebase/analytics": "0.10.1", - "@firebase/analytics-types": "0.8.0", - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/analytics-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz", - "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==" - }, - "node_modules/@firebase/app": { - "version": "0.9.29", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.29.tgz", - "integrity": "sha512-HbKTjfmILklasIu/ij6zKnFf3SgLYXkBDVN7leJfVGmohl+zA7Ig+eXM1ZkT1pyBJ8FTYR+mlOJer/lNEnUCtw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "idb": "7.1.1", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/app-check": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.2.tgz", - "integrity": "sha512-A2B5+ldOguYAeqW1quFN5qNdruSNRrg4W59ag1Eq6QzxuHNIkrE+TrapfrW/z5NYFjCxAYqr/unVCgmk80Dwcg==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/app-check-compat": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.9.tgz", - "integrity": "sha512-7LxyupQ8XeEHRh72mO+tqm69kHT6KbWi2KtFMGedJ6tNbwzFzojcXESMKN8RpADXbYoQgY3loWMJjMx4r2Zt7w==", - "dependencies": { - "@firebase/app-check": "0.8.2", - "@firebase/app-check-types": "0.5.0", - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/app-check-interop-types": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", - "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" - }, - "node_modules/@firebase/app-check-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz", - "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==" - }, - "node_modules/@firebase/app-compat": { - "version": "0.2.29", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.29.tgz", - "integrity": "sha512-NqUdegXJfwphx9i/2bOE2CTZ55TC9bbDg+iwkxVShsPBJhD3CzQJkFhoDz4ccfbJaKZGsqjY3fisgX5kbDROnA==", - "dependencies": { - "@firebase/app": "0.9.29", - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/app-types": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", - "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" - }, - "node_modules/@firebase/auth": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.6.2.tgz", - "integrity": "sha512-BFo/Nj1AAbKLbFiUyXCcnT/bSqMJicFOgdTAKzlXvCul7+eUE29vWmzd1g59O3iKAxvv3+fbQYjQVJpNTTHIyw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.28.3" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" - }, - "peerDependenciesMeta": { - "@react-native-async-storage/async-storage": { - "optional": true - } - } - }, - "node_modules/@firebase/auth-compat": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.4.tgz", - "integrity": "sha512-EtRVW9s0YsuJv3GnOGDoLUW3Pp9f3HcqWA2WK92E30Qa0FEVRwCSRLVQwn9td+SLVY3AP9gi/auC1q3osd4yCg==", - "dependencies": { - "@firebase/auth": "1.6.2", - "@firebase/auth-types": "0.12.0", - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.28.3" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", - "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" - }, - "node_modules/@firebase/auth-types": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", - "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/component": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", - "integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==", - "dependencies": { - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.3.tgz", - "integrity": "sha512-9fjqLt9JzL46gw9+NRqsgQEMjgRwfd8XtzcKqG+UYyhVeFCdVRQ0Wp6Dw/dvYHnbH5vNEKzNv36dcB4p+PIAAA==", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.0", - "@firebase/auth-interop-types": "0.2.1", - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.3.tgz", - "integrity": "sha512-7tHEOcMbK5jJzHWyphPux4osogH/adWwncxdMxdBpB9g1DNIyY4dcz1oJdlkXGM/i/AjUBesZsd5CuwTRTBNTw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/database": "1.0.3", - "@firebase/database-types": "1.0.1", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.1.tgz", - "integrity": "sha512-Tmcmx5XgiI7UVF/4oGg2P3AOTfq3WKEPsm2yf+uXtN7uG/a4WTWhVMrXGYRY2ZUL1xPxv9V33wQRJ+CcrUhVXw==", - "dependencies": { - "@firebase/app-types": "0.9.0", - "@firebase/util": "1.9.4" - } - }, - "node_modules/@firebase/firestore": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.5.0.tgz", - "integrity": "sha512-rXS6v4HbsN6vZQlq2fLW1ZHb+J5SnS+8Zqb/McbKFIrGYjPUZo5CyO75mkgtlR1tCYAwCebaqoEWb6JHgZv/ww==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "@firebase/webchannel-wrapper": "0.10.5", - "@grpc/grpc-js": "~1.9.0", - "@grpc/proto-loader": "^0.7.8", - "tslib": "^2.1.0", - "undici": "5.28.3" - }, - "engines": { - "node": ">=10.10.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/firestore-compat": { - "version": "0.3.27", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.27.tgz", - "integrity": "sha512-gY2q0fCDJvPg/IurZQbBM7MIVjxA1/LsvfgFOubUTrex5KTY9qm4/2V2R79eAs8Q+b4B8soDtlEjk6L8BW1Crw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/firestore": "4.5.0", - "@firebase/firestore-types": "3.0.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/firestore-types": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.0.tgz", - "integrity": "sha512-Meg4cIezHo9zLamw0ymFYBD4SMjLb+ZXIbuN7T7ddXN6MGoICmOTq3/ltdCGoDCS2u+H1XJs2u/cYp75jsX9Qw==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/functions": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.2.tgz", - "integrity": "sha512-2NULTYOZbu0rXczwfYdqQH0w1FmmYrKjTy1YPQSHLCAkMBdfewoKmVm4Lyo2vRn0H9ZndciLY7NszKDFt9MKCQ==", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.0", - "@firebase/auth-interop-types": "0.2.1", - "@firebase/component": "0.6.5", - "@firebase/messaging-interop-types": "0.2.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.28.3" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/functions-compat": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.8.tgz", - "integrity": "sha512-VDHSw6UOu8RxfgAY/q8e+Jn+9Fh60Fc28yck0yfMsi2e0BiWgonIMWkFspFGGLgOJebTHl+hc+9v91rhzU6xlg==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/functions": "0.11.2", - "@firebase/functions-types": "0.6.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/functions-types": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz", - "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==" - }, - "node_modules/@firebase/installations": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.5.tgz", - "integrity": "sha512-0xxnQWw8rSRzu0ZOCkZaO+MJ0LkDAfwwTB2Z1SxRK6FAz5xkxD1ZUwM0WbCRni49PKubCrZYOJ6yg7tSjU7AKA==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/installations-compat": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.5.tgz", - "integrity": "sha512-usvoIaog5CHEw082HXLrKAZ1qd4hIC3N/LDe2NqBgI3pkGE/7auLVM4Gn5gvyryp0x8z/IP1+d9fkGUj2OaGLQ==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/installations-types": "0.5.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/installations-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz", - "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==", - "peerDependencies": { - "@firebase/app-types": "0.x" - } - }, - "node_modules/@firebase/logger": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", - "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/messaging": { - "version": "0.12.6", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.6.tgz", - "integrity": "sha512-IORsPp9IPWq4j4yEhTOZ6GAGi3gQwGc+4yexmTAlya+qeBRSdRnJg2iIU/aj+tcKDQYr9RQuQPgHHOdFIx//vA==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/messaging-interop-types": "0.2.0", - "@firebase/util": "1.9.4", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/messaging-compat": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.6.tgz", - "integrity": "sha512-Q2xC1s4L7Vpss7P7Gy6GuIS+xmJrf/vm9+gX76IK1Bo1TjoKwleCLHt1LHkPz5Rvqg5pTgzzI8qqPhBpZosFCg==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/messaging": "0.12.6", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/messaging-interop-types": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", - "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==" - }, - "node_modules/@firebase/performance": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.5.tgz", - "integrity": "sha512-OzAGcWhOqEFH9GdwUuY0oC5FSlnMejcnmSAhR+EjpI7exdDvixyLyCR4txjSHYNTbumrFBG+EP8GO11CNXRaJA==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/performance-compat": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.5.tgz", - "integrity": "sha512-jJwJkVyDcIMBaVGrZ6CRGs4m5FCZsWB5QCWYI3FdsHyIa9/TfteNDilxj9wGciF2naFIHDW7TgE69U5dAH9Ktg==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/performance": "0.6.5", - "@firebase/performance-types": "0.2.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/performance-types": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz", - "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==" - }, - "node_modules/@firebase/remote-config": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.5.tgz", - "integrity": "sha512-rGLqc/4OmxrS39RA9kgwa6JmgWytQuMo+B8pFhmGp3d++x2Hf9j+MLQfhOLyyUo64fNw20J19mLXhrXvKHsjZQ==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/remote-config-compat": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.5.tgz", - "integrity": "sha512-ImkNnLuGrD/bylBHDJigSY6LMwRrwt37wQbsGZhWG4QQ6KLzHzSf0nnFRRFvkOZodEUE57Ib8l74d6Yn/6TDUQ==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/remote-config": "0.4.5", - "@firebase/remote-config-types": "0.3.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/remote-config-types": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz", - "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==" - }, - "node_modules/@firebase/storage": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.12.2.tgz", - "integrity": "sha512-MzanOBcxDx9oOwDaDPMuiYxd6CxcN1xZm+os5uNE3C1itbRKLhM9rzpODDKWzcbnHHFtXk3Q3lsK/d3Xa1WYYw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.28.3" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/storage-compat": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.5.tgz", - "integrity": "sha512-5dJXfY5NxCF5NAk4dLvJqC+m6cgcf0Fr29nrMHwhwI34pBheQq2PdRZqALsqZCES9dnHTuFNlqGQDpLr+Ph4rw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/storage": "0.12.2", - "@firebase/storage-types": "0.8.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/storage-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz", - "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/util": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", - "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/webchannel-wrapper": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.5.tgz", - "integrity": "sha512-eSkJsnhBWv5kCTSU1tSUVl9mpFu+5NXXunZc83le8GMjMlsWwQArSc7cJJ4yl+aDFY0NGLi0AjZWMn1axOrkRg==" - }, "node_modules/@floating-ui/core": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", @@ -5399,9 +5479,9 @@ } }, "node_modules/@grpc/proto-loader": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", - "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.12.tgz", + "integrity": "sha512-DCVwMxqYzpUCiDMl7hQ384FqP4T3DbNpXU8pt681l3UWCip1WUiD5JrkImUwCB9a7f2cq4CUTmi5r/xIMRPY1Q==", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", @@ -10814,12 +10894,12 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -10827,7 +10907,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -11682,9 +11762,30 @@ } }, "node_modules/cohere-ai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/cohere-ai/-/cohere-ai-6.2.2.tgz", - "integrity": "sha512-+Tq+4e8N/YWKJqFpWaULsfbZR/GOvGh8WWYFKR1bpipu8bCok3VcbTPnBmIToQiIqOgFpGk3HsA4b0guVyL3vg==" + "version": "7.9.1", + "resolved": "https://registry.npmjs.org/cohere-ai/-/cohere-ai-7.9.1.tgz", + "integrity": "sha512-shMz0Bs3p6/Nw5Yi+6Wc9tZ7DCGTtEnf1eAcuesnlyeKoFuZ7+bzeiHkt5E8SvTgAHxN1GCP3UkIoW85QhHKTA==", + "dependencies": { + "form-data": "4.0.0", + "js-base64": "3.7.2", + "node-fetch": "2.7.0", + "qs": "6.11.2", + "url-join": "4.0.1" + } + }, + "node_modules/cohere-ai/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/collect-v8-coverage": { "version": "1.0.2", @@ -13767,16 +13868,16 @@ "integrity": "sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==" }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -13870,6 +13971,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -14377,39 +14486,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/firebase": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.9.0.tgz", - "integrity": "sha512-R8rDU3mg2dq0uPOoZ5Nc3BeZTbXxBPJS8HcZLtnV0f5/YrmpNsHngzmMHRVB+91T+ViJGVL/42dV23gS9w9ccw==", - "dependencies": { - "@firebase/analytics": "0.10.1", - "@firebase/analytics-compat": "0.2.7", - "@firebase/app": "0.9.29", - "@firebase/app-check": "0.8.2", - "@firebase/app-check-compat": "0.3.9", - "@firebase/app-compat": "0.2.29", - "@firebase/app-types": "0.9.0", - "@firebase/auth": "1.6.2", - "@firebase/auth-compat": "0.5.4", - "@firebase/database": "1.0.3", - "@firebase/database-compat": "1.0.3", - "@firebase/firestore": "4.5.0", - "@firebase/firestore-compat": "0.3.27", - "@firebase/functions": "0.11.2", - "@firebase/functions-compat": "0.3.8", - "@firebase/installations": "0.6.5", - "@firebase/installations-compat": "0.2.5", - "@firebase/messaging": "0.12.6", - "@firebase/messaging-compat": "0.2.6", - "@firebase/performance": "0.6.5", - "@firebase/performance-compat": "0.2.5", - "@firebase/remote-config": "0.4.5", - "@firebase/remote-config-compat": "0.2.5", - "@firebase/storage": "0.12.2", - "@firebase/storage-compat": "0.3.5", - "@firebase/util": "1.9.4" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -17678,6 +17754,11 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + }, "node_modules/js-tiktoken": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.10.tgz", @@ -23418,9 +23499,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -26476,9 +26557,9 @@ "dev": true }, "node_modules/undici": { - "version": "5.28.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", - "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", "dependencies": { "@fastify/busboy": "^2.0.0" }, @@ -26743,6 +26824,11 @@ "qs": "^6.11.2" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", diff --git a/packages/data-provider/package.json b/packages/data-provider/package.json index b01e3dc72..a662e43aa 100644 --- a/packages/data-provider/package.json +++ b/packages/data-provider/package.json @@ -1,6 +1,6 @@ { "name": "librechat-data-provider", - "version": "0.5.1", + "version": "0.5.2", "description": "data services for librechat apps", "main": "dist/index.js", "module": "dist/index.es.js", diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index 89b4a9ced..a855babd3 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -238,6 +238,7 @@ export enum KnownEndpoints { ollama = 'ollama', perplexity = 'perplexity', 'together.ai' = 'together.ai', + cohere = 'cohere', } export enum FetchTokenConfig { @@ -532,6 +533,32 @@ export enum Constants { NO_PARENT = '00000000-0000-0000-0000-000000000000', } +/** + * Enum for Cohere related constants + */ +export enum CohereConstants { + /** + * Cohere API Endpoint, for special handling + */ + API_URL = 'https://api.cohere.ai/v1', + /** + * Role for "USER" messages + */ + ROLE_USER = 'USER', + /** + * Role for "SYSTEM" messages + */ + ROLE_SYSTEM = 'SYSTEM', + /** + * Role for "CHATBOT" messages + */ + ROLE_CHATBOT = 'CHATBOT', + /** + * Title message as required by Cohere + */ + TITLE_MESSAGE = 'TITLE:', +} + export const defaultOrderQuery: { order: 'desc'; limit: 100;