LibreChat/api/server/routes/edit/anthropic.js

146 lines
3.9 KiB
JavaScript
Raw Normal View History

feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
const express = require('express');
const router = express.Router();
const { getResponseSender } = require('../endpoints/schemas');
const { initializeClient } = require('../endpoints/anthropic');
const {
handleAbort,
createAbortController,
handleAbortError,
setHeaders,
validateEndpoint,
buildEndpointOption,
} = require('../../middleware');
const { saveMessage, getConvoTitle, getConvo } = require('../../../models');
const { sendMessage, createOnProgress } = require('../../utils');
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
router.post('/abort', handleAbort());
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
router.post('/', validateEndpoint, buildEndpointOption, setHeaders, async (req, res) => {
let {
text,
generation,
endpointOption,
conversationId,
responseMessageId,
isContinued = false,
parentMessageId = null,
overrideParentMessageId = null,
} = req.body;
console.log('edit log');
console.dir({ text, generation, isContinued, conversationId, endpointOption }, { depth: null });
let metadata;
let userMessage;
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
let promptTokens;
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
let lastSavedTimestamp = 0;
let saveDelay = 100;
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
const sender = getResponseSender(endpointOption);
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
const userMessageId = parentMessageId;
const user = req.user.id;
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
const addMetadata = (data) => (metadata = data);
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
const getReqData = (data = {}) => {
for (let key in data) {
if (key === 'userMessage') {
userMessage = data[key];
} else if (key === 'responseMessageId') {
responseMessageId = data[key];
} else if (key === 'promptTokens') {
promptTokens = data[key];
}
}
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
};
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
const { onProgress: progressCallback, getPartialText } = createOnProgress({
generation,
onProgress: ({ text: partialText }) => {
const currentTimestamp = Date.now();
if (currentTimestamp - lastSavedTimestamp > saveDelay) {
lastSavedTimestamp = currentTimestamp;
saveMessage({
messageId: responseMessageId,
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
sender,
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
conversationId,
parentMessageId: overrideParentMessageId ?? userMessageId,
text: partialText,
unfinished: true,
cancelled: false,
isEdited: true,
error: false,
user,
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
});
}
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
if (saveDelay < 500) {
saveDelay = 500;
}
},
});
try {
const getAbortData = () => ({
conversationId,
messageId: responseMessageId,
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
sender,
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
parentMessageId: overrideParentMessageId ?? userMessageId,
text: getPartialText(),
userMessage,
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
promptTokens,
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
});
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
const { abortController, onStart } = createAbortController(req, res, getAbortData);
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
const { client } = await initializeClient({ req, res, endpointOption });
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
let response = await client.sendMessage(text, {
user,
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
generation,
isContinued,
isEdited: true,
conversationId,
parentMessageId,
responseMessageId,
overrideParentMessageId,
...endpointOption,
onProgress: progressCallback.call(null, {
res,
text,
parentMessageId: overrideParentMessageId ?? userMessageId,
}),
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
getReqData,
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
onStart,
addMetadata,
abortController,
});
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
if (metadata) {
response = { ...response, ...metadata };
}
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
if (overrideParentMessageId) {
response.parentMessageId = overrideParentMessageId;
}
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
await saveMessage({ ...response, user });
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
sendMessage(res, {
title: await getConvoTitle(user, conversationId),
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
final: true,
conversation: await getConvo(user, conversationId),
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
requestMessage: userMessage,
responseMessage: response,
});
res.end();
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
// TODO: add anthropic titling
} catch (error) {
const partialText = getPartialText();
handleAbortError(res, req, error, {
partialText,
conversationId,
feat: Accurate Token Usage Tracking & Optional Balance (#1018) * refactor(Chains/llms): allow passing callbacks * refactor(BaseClient): accurately count completion tokens as generation only * refactor(OpenAIClient): remove unused getTokenCountForResponse, pass streaming var and callbacks in initializeLLM * wip: summary prompt tokens * refactor(summarizeMessages): new cut-off strategy that generates a better summary by adding context from beginning, truncating the middle, and providing the end wip: draft out relevant providers and variables for token tracing * refactor(createLLM): make streaming prop false by default * chore: remove use of getTokenCountForResponse * refactor(agents): use BufferMemory as ConversationSummaryBufferMemory token usage not easy to trace * chore: remove passing of streaming prop, also console log useful vars for tracing * feat: formatFromLangChain helper function to count tokens for ChatModelStart * refactor(initializeLLM): add role for LLM tracing * chore(formatFromLangChain): update JSDoc * feat(formatMessages): formats langChain messages into OpenAI payload format * chore: install openai-chat-tokens * refactor(formatMessage): optimize conditional langChain logic fix(formatFromLangChain): fix destructuring * feat: accurate prompt tokens for ChatModelStart before generation * refactor(handleChatModelStart): move to callbacks dir, use factory function * refactor(initializeLLM): rename 'role' to 'context' * feat(Balance/Transaction): new schema/models for tracking token spend refactor(Key): factor out model export to separate file * refactor(initializeClient): add req,res objects to client options * feat: add-balance script to add to an existing users' token balance refactor(Transaction): use multiplier map/function, return balance update * refactor(Tx): update enum for tokenType, return 1 for multiplier if no map match * refactor(Tx): add fair fallback value multiplier incase the config result is undefined * refactor(Balance): rename 'tokens' to 'tokenCredits' * feat: balance check, add tx.js for new tx-related methods and tests * chore(summaryPrompts): update prompt token count * refactor(callbacks): pass req, res wip: check balance * refactor(Tx): make convoId a String type, fix(calculateTokenValue) * refactor(BaseClient): add conversationId as client prop when assigned * feat(RunManager): track LLM runs with manager, track token spend from LLM, refactor(OpenAIClient): use RunManager to create callbacks, pass user prop to langchain api calls * feat(spendTokens): helper to spend prompt/completion tokens * feat(checkBalance): add helper to check, log, deny request if balance doesn't have enough funds refactor(Balance): static check method to return object instead of boolean now wip(OpenAIClient): implement use of checkBalance * refactor(initializeLLM): add token buffer to assure summary isn't generated when subsequent payload is too large refactor(OpenAIClient): add checkBalance refactor(createStartHandler): add checkBalance * chore: remove prompt and completion token logging from route handler * chore(spendTokens): add JSDoc * feat(logTokenCost): record transactions for basic api calls * chore(ask/edit): invoke getResponseSender only once per API call * refactor(ask/edit): pass promptTokens to getIds and include in abort data * refactor(getIds -> getReqData): rename function * refactor(Tx): increase value if incomplete message * feat: record tokenUsage when message is aborted * refactor: subtract tokens when payload includes function_call * refactor: add namespace for token_balance * fix(spendTokens): only execute if corresponding token type amounts are defined * refactor(checkBalance): throws Error if not enough token credits * refactor(runTitleChain): pass and use signal, spread object props in create helpers, and use 'call' instead of 'run' * fix(abortMiddleware): circular dependency, and default to empty string for completionTokens * fix: properly cancel title requests when there isn't enough tokens to generate * feat(predictNewSummary): custom chain for summaries to allow signal passing refactor(summaryBuffer): use new custom chain * feat(RunManager): add getRunByConversationId method, refactor: remove run and throw llm error on handleLLMError * refactor(createStartHandler): if summary, add error details to runs * fix(OpenAIClient): support aborting from summarization & showing error to user refactor(summarizeMessages): remove unnecessary operations counting summaryPromptTokens and note for alternative, pass signal to summaryBuffer * refactor(logTokenCost -> recordTokenUsage): rename * refactor(checkBalance): include promptTokens in errorMessage * refactor(checkBalance/spendTokens): move to models dir * fix(createLanguageChain): correctly pass config * refactor(initializeLLM/title): add tokenBuffer of 150 for balance check * refactor(openAPIPlugin): pass signal and memory, filter functions by the one being called * refactor(createStartHandler): add error to run if context is plugins as well * refactor(RunManager/handleLLMError): throw error immediately if plugins, don't remove run * refactor(PluginsClient): pass memory and signal to tools, cleanup error handling logic * chore: use absolute equality for addTitle condition * refactor(checkBalance): move checkBalance to execute after userMessage and tokenCounts are saved, also make conditional * style: icon changes to match official * fix(BaseClient): getTokenCountForResponse -> getTokenCount * fix(formatLangChainMessages): add kwargs as fallback prop from lc_kwargs, update JSDoc * refactor(Tx.create): does not update balance if CHECK_BALANCE is not enabled * fix(e2e/cleanUp): cleanup new collections, import all model methods from index * fix(config/add-balance): add uncaughtException listener * fix: circular dependency * refactor(initializeLLM/checkBalance): append new generations to errorMessage if cost exceeds balance * fix(handleResponseMessage): only record token usage in this method if not error and completion is not skipped * fix(createStartHandler): correct condition for generations * chore: bump postcss due to moderate severity vulnerability * chore: bump zod due to low severity vulnerability * chore: bump openai & data-provider version * feat(types): OpenAI Message types * chore: update bun lockfile * refactor(CodeBlock): add error block formatting * refactor(utils/Plugin): factor out formatJSON and cn to separate files (json.ts and cn.ts), add extractJSON * chore(logViolation): delete user_id after error is logged * refactor(getMessageError -> Error): change to React.FC, add token_balance handling, use extractJSON to determine JSON instead of regex * fix(DALL-E): use latest openai SDK * chore: reorganize imports, fix type issue * feat(server): add balance route * fix(api/models): add auth * feat(data-provider): /api/balance query * feat: show balance if checking is enabled, refetch on final message or error * chore: update docs, .env.example with token_usage info, add balance script command * fix(Balance): fallback to empty obj for balance query * style: slight adjustment of balance element * docs(token_usage): add PR notes
2023-10-05 18:34:10 -04:00
sender,
feat: Message Rate Limiters, Violation Logging, & Ban System 🔨 (#903) * refactor: require Auth middleware in route index files * feat: concurrent message limiter * feat: complete concurrent message limiter with caching * refactor: SSE response methods separated from handleText * fix(abortMiddleware): fix req and res order to standard, use endpointOption in req.body * chore: minor name changes * refactor: add isUUID condition to saveMessage * fix(concurrentLimiter): logic correctly handles the max number of concurrent messages and res closing/finalization * chore: bump keyv and remove console.log from Message * fix(concurrentLimiter): ensure messages are only saved in later message children * refactor(concurrentLimiter): use KeyvFile instead, could make other stores configurable in the future * feat: add denyRequest function for error responses * feat(utils): add isStringTruthy function Introduce the isStringTruthy function to the utilities module to check if a string value is a case-insensitive match for 'true' * feat: add optional message rate limiters by IP and userId * feat: add optional message rate limiters by IP and userId to edit route * refactor: rename isStringTruthy to isTrue for brevity * refactor(getError): use map to make code cleaner * refactor: use memory for concurrent rate limiter to prevent clearing on startup/exit, add multiple log files, fix error message for concurrent violation * feat: check if errorMessage is object, stringify if so * chore: send object to denyRequest which will stringify it * feat: log excessive requests * fix(getError): correctly pluralize messages * refactor(limiters): make type consistent between logs and errorMessage * refactor(cache): move files out of lib/db into separate cache dir >> feat: add getLogStores function so Keyv instance is not redundantly created on every violation feat: separate violation logging to own function with logViolation * fix: cache/index.js export, properly record userViolations * refactor(messageLimiters): use new logging method, add logging to registrations * refactor(logViolation): make userLogs an array of logs per user * feat: add logging to login limiter * refactor: pass req as first param to logViolation and record offending IP * refactor: rename isTrue helper fn to isEnabled * feat: add simple non_browser check and log violation * fix: open handles in unit tests, remove KeyvMongo as not used and properly mock global fetch * chore: adjust nodemon ignore paths to properly ignore logs * feat: add math helper function for safe use of eval * refactor(api/convos): use middleware at top of file to avoid redundancy * feat: add delete all static method for Sessions * fix: redirect to login on refresh if user is not found, or the session is not found but hasn't expired (ban case) * refactor(getLogStores): adjust return type * feat: add ban violation and check ban logic refactor(logViolation): pass both req and res objects * feat: add removePorts helper function * refactor: rename getError to getMessageError and add getLoginError for displaying different login errors * fix(AuthContext): fix type issue and remove unused code * refactor(bans): ban by ip and user id, send response based on origin * chore: add frontend ban messages * refactor(routes/oauth): add ban check to handler, also consolidate logic to avoid redundancy * feat: add ban check to AI messaging routes * feat: add ban check to login/registration * fix(ci/api): mock KeyvMongo to avoid tests hanging * docs: update .env.example > refactor(banViolation): calculate interval rate crossover, early return if duration is invalid ci(banViolation): add tests to ensure users are only banned when expected * docs: improve wording for mod system * feat: add configurable env variables for violation scores * chore: add jsdoc for uaParser.js * chore: improve ban text log * chore: update bun test scripts * refactor(math.js): add fallback values * fix(KeyvMongo/banLogs): refactor keyv instances to top of files to avoid memory leaks, refactor ban logic to use getLogStores instead refactor(getLogStores): get a single log store by type * fix(ci): refactor tests due to banLogs changes, also make sure to clear and revoke sessions even if ban duration is 0 * fix(banViolation.js): getLogStores import * feat: handle 500 code error at login * fix(middleware): handle case where user.id is _id and not just id * ci: add ban secrets for backend unit tests * refactor: logout user upon ban * chore: log session delete message only if deletedCount > 0 * refactor: change default ban duration (2h) and make logic more clear in JSDOC * fix: login and registration limiters will now return rate limiting error * fix: userId not parsable as non ObjectId string * feat: add useTimeout hook to properly clear timeouts when invoking functions within them refactor(AuthContext): cleanup code by using new hook and defining types in ~/common * fix: login error message for rate limits * docs: add info for automated mod system and rate limiters, update other docs accordingly * chore: bump data-provider version
2023-09-13 10:57:07 -04:00
messageId: responseMessageId,
parentMessageId: userMessageId ?? parentMessageId,
});
}
});
feat(GPT/Anthropic): Continue Regenerating & Generation Buttons (#808) * feat(useMessageHandler.js/ts): Refactor and add features to handle user messages, support multiple endpoints/models, generate placeholder responses, regeneration, and stopGeneration function fix(conversation.ts, buildTree.ts): Import TMessage type, handle null parentMessageId feat(schemas.ts): Update and add schemas for various AI services, add default values, optional fields, and endpoint-to-schema mapping, create parseConvo function chore(useMessageHandler.js, schemas.ts): Remove unused imports, variables, and chatGPT enum * wip: add generation buttons * refactor(cleanupPreset.ts): simplify cleanupPreset function refactor(getDefaultConversation.js): remove unused code and simplify getDefaultConversation function feat(utils): add getDefaultConversation function This commit adds a new utility function called `getDefaultConversation` to the `client/src/utils/getDefaultConversation.ts` file. This function is responsible for generating a default conversation object based on the provided parameters. The `getDefaultConversation` function takes in an object with the following properties: - `conversation`: The conversation object to be used as a base. - `endpointsConfig`: The configuration object containing information about the available endpoints. - `preset`: An optional preset object that can be used to override the default behavior. The function first tries to determine the target endpoint based on the preset object. If a valid endpoint is found, it is used as the target endpoint. If not, the function tries to retrieve the last conversation setup from the local storage and uses its endpoint if it is valid. If neither the preset nor the local storage contains a valid endpoint, the function falls back to a default endpoint. Once the target endpoint is determined, * fix(utils): remove console.error statement in buildDefaultConversation function fix(schemas): add default values for catch blocks in openAISchema, googleSchema, bingAISchema, anthropicSchema, chatGPTBrowserSchema, and gptPluginsSchema * fix: endpoint not changing on change of preset from other endpoint, wip: refactor * refactor: preset items to TSX * refactor: convert resetConvo to TS * refactor(getDefaultConversation.ts): move defaultEndpoints array to the top of the file for better readability refactor(getDefaultConversation.ts): extract getDefaultEndpoint function for better code organization and reusability * feat(svg): add ContinueIcon component feat(svg): add RegenerateIcon component feat(svg): add ContinueIcon and RegenerateIcon components to index.ts * feat(Button.tsx): add onClick and className props to Button component feat(GenerationButtons.tsx): add logic to display Regenerate or StopGenerating button based on isSubmitting and messages feat(Regenerate.tsx): create Regenerate component with RegenerateIcon and handleRegenerate function feat(StopGenerating.tsx): create StopGenerating component with StopGeneratingIcon and handleStopGenerating function * fix(TextChat.jsx): reorder imports and variables for better readability fix(TextChat.jsx): fix typo in condition for isNotAppendable variable fix(TextChat.jsx): remove unused handleStopGenerating function fix(ContinueIcon.tsx): remove unnecessary closing tags for polygon elements fix(useMessageHandler.ts): add missing type annotations for handleStopGenerating and handleRegenerate functions fix(useMessageHandler.ts): remove unused variables in return statement * fix(getDefaultConversation.ts): refactor code to use getLocalStorageItems function feat(getLocalStorageItems.ts): add utility function to retrieve items from local storage * fix(OpenAIClient.js): add support for streaming result in sendCompletion method feat(OpenAIClient.js): add finish_reason metadata to opts in sendCompletion method feat(Message.js): add finish_reason field to Message model feat(messageSchema.js): add finish_reason field to messageSchema feat(openAI.js): parse chatGptLabel and promptPrefix from req.body and pass rest of the modelOptions to endpointOption feat(openAI.js): add addMetadata function to store metadata in ask function feat(openAI.js): add metadata to response if available feat(schemas.ts): add finish_reason field to tMessageSchema * feat(types.ts): add TOnClick and TGenButtonProps types for button components feat(Continue.tsx): create Continue component for generating button feat(GenerationButtons.tsx): update GenerationButtons component to use Continue component feat(Regenerate.tsx): create Regenerate component for regenerating button feat(Stop.tsx): create Stop component for stop generating button * feat(MessageHandler.jsx): add MessageHandler component to handle messages and conversations fix(Root.jsx): fix import paths for Nav and MessageHandler components * feat(useMessageHandler.ts): add support for generation parameter in ask function feat(useMessageHandler.ts): add support for isEdited parameter in ask function feat(useMessageHandler.ts): add support for continueGeneration function fix(createPayload.ts): replace endpoint URL when isEdited parameter is true * chore(client): set skipLibCheck to true in tsconfig.json * fix(useMessageHandler.ts): remove unused clientId variable fix(schemas.ts): make clientId field in tMessageSchema nullable and optional * wip: edit route for continue generation * refactor(api): move handlers to root of routes dir * fix(useMessageHandler.ts): initialize currentMessages to an empty array if messages is null fix(useMessageHandler.ts): update initialResponse text to use responseText variable fix(useMessageHandler.ts): update setMessages logic for isRegenerate case fix(MessageHandler.jsx): update setMessages logic for cancelHandler, createdHandler, and finalHandler * fix(schemas.ts): make createdAt and updatedAt fields optional and set default values using new Date().toISOString() fix(schemas.ts): change type annotation of TMessage from infer to input * refactor(useMessageHandler.ts): rename AskProps type to TAskProps refactor(useMessageHandler.ts): remove generation property from ask function arguments refactor(useMessageHandler.ts): use nullish coalescing operator (??) instead of logical OR (||) refactor(useMessageHandler.ts): pass the responseMessageId to message prop of submission * fix(BaseClient.js): use nullish coalescing operator (??) instead of logical OR (||) for default values * fix(BaseClient.js): fix responseMessageId assignment in handleStartMethods method feat(BaseClient.js): add support for isEdited flag in sendMessage method feat(BaseClient.js): add generation to responseMessage text in sendMessage method * fix(openAI.js): remove unused imports and commented out code feat(openAI.js): add support for generation parameter in request body fix(openAI.js): remove console.log statement fix(openAI.js): remove unused variables and parameters fix(openAI.js): update response text in case of error fix(openAI.js): handle error and abort message in case of error fix(handlers.js): add generation parameter to createOnProgress function fix(useMessageHandler.ts): update responseText variable to use generation parameter * refactor(api/middleware): move inside server dir * refactor: add endpoint specific, modular functions to build options and initialize clients, create server/utils, move middleware, separate utils into api general utils and server specific utils * fix(abortMiddleware.js): import getConvo and getConvoTitle functions from models feat(abortMiddleware.js): add abortAsk function to abortController to handle aborting of requests fix(openAI.js): import buildOptions and initializeClient functions from endpoints/openAI refactor(openAI.js): use getAbortData function to get data for abortAsk function * refactor: move endpoint specific logic to an endpoints dir * refactor(PluginService.js): fix import path for encrypt and decrypt functions in PluginService.js * feat(openAI): add new endpoint for adding a title to a conversation - Added a new file `addTitle.js` in the `api/server/routes/endpoints/openAI` directory. - The `addTitle.js` file exports a function `addTitle` that takes in request parameters and performs the following actions: - If the `parentMessageId` is `'00000000-0000-0000-0000-000000000000'` and `newConvo` is true, it proceeds with the following steps: - Calls the `titleConvo` function from the `titleConvo` module, passing in the necessary parameters. - Calls the `saveConvo` function from the `saveConvo` module, passing in the user ID and conversation details. - Updated the `index.js` file in the `api/server/routes/endpoints/openAI` directory to export the `addTitle` function. - This change adds * fix(abortMiddleware.js): remove console.log statement refactor(gptPlugins.js): update imports and function parameters feat(gptPlugins.js): add support for abortController and getAbortData refactor(openAI.js): update imports and function parameters feat(openAI.js): add support for abortController and getAbortData fix(openAI.js): refactor code to use modularized functions and middleware fix(buildOptions.js): refactor code to use destructuring and update variable names * refactor(askChatGPTBrowser.js, bingAI.js, google.js): remove duplicate code for setting response headers feat(askChatGPTBrowser.js, bingAI.js, google.js): add setHeaders middleware to set response headers * feat(middleware): validateEndpoint, refactor buildOption to only be concerned of endpointOption * fix(abortMiddleware.js): add 'finish_reason' property with value 'incomplete' to responseMessage object fix(abortMessage.js): remove console.log statement for aborted message fix(handlers.js): modify tokens assignment to handle empty generation string and trailing space * fix(BaseClient.js): import addSpaceIfNeeded function from server/utils fix(BaseClient.js): add space before generation in text property fix(index.js): remove getCitations and citeText exports feat(buildEndpointOption.js): add buildEndpointOption middleware fix(index.js): import buildEndpointOption middleware fix(anthropic.js): remove buildOptions function and use endpointOption from req.body fix(gptPlugins.js): remove buildOptions function and use endpointOption from req.body fix(openAI.js): remove buildOptions function and use endpointOption from req.body feat(utils): add citations.js and handleText.js modules fix(utils): fix import statements in index.js module * refactor(gptPlugins.js): use getResponseSender function from librechat-data-provider * feat(gptPlugins): complete 'continue generating' * wip: anthropic continue regen * feat(middleware): add validateRegistration middleware A new middleware function called `validateRegistration` has been added to the list of exported middleware functions in `index.js`. This middleware is responsible for validating registration data before allowing the registration process to proceed. * feat(Anthropic): complete continue regen * chore: add librechat-data-provider to api/package.json * fix(ci): backend-review will mock meilisearch, also installs data-provider as now needed * chore(ci): remove unneeded SEARCH env var * style(GenerationButtons): make text shorter for sake of space economy, even though this diverges from chat.openai.com * style(GenerationButtons/ScrollToBottom): adjust visibility/position based on screen size * chore(client): 'Editting' typo * feat(GenerationButtons.tsx): add support for endpoint prop in GenerationButtons component feat(OptionsBar.tsx): pass endpoint prop to GenerationButtons component feat(useGenerations.ts): create useGenerations hook to handle generation logic fix(schemas.ts): add searchResult field to tMessageSchema * refactor(HoverButtons): convert to TSX and utilize new useGenerations hook * fix(abortMiddleware): handle error with res headers set, or abortController not found, to ensure proper API error is sent to the client, chore(BaseClient): remove console log for onStart message meant for debugging * refactor(api): remove librechat-data-provider dep for now as it complicates deployed docker build stage, re-use code in CJS, located in server/endpoints/schemas * chore: remove console.logs from test files * ci: add backend tests for AnthropicClient, focusing on new buildMessages logic * refactor(FakeClient): use actual BaseClient sendMessage method for testing * test(BaseClient.test.js): add test for loading chat history test(BaseClient.test.js): add test for sendMessage logic with isEdited flag * fix(buildEndpointOption.js): add support for azureOpenAI in buildFunction object wip(endpoints.js): fetch Azure models from Azure OpenAI API if opts.azure is true * fix(Button.tsx): add data-testid attribute to button component fix(SelectDropDown.tsx): add data-testid attribute to Listbox.Button component fix(messages.spec.ts): add waitForServerStream function to consolidate logic for awaiting the server response feat(messages.spec.ts): add test for stopping and continuing message and improve browser/page context order and closing * refactor(onProgress): speed up time to save initial message for editable routes * chore: disable AI message editing (for now), was accidentally allowed * refactor: ensure continue is only supported for latest message style: improve styling in dark mode and across all hover buttons/icons, including making edit icon for AI invisible (for now) * fix: add test id to generation buttons so they never resolve to 2+ items * chore(package.json): add 'packages/' to the list of ignored directories chore(data-provider/package.json): bump version to 0.1.5
2023-08-17 12:50:05 -04:00
module.exports = router;