From e5336039fc5fb3f92f8d6a8d7c42f1b8462a32ed Mon Sep 17 00:00:00 2001 From: Danny Avila <110412045+danny-avila@users.noreply.github.com> Date: Fri, 14 Jul 2023 09:36:49 -0400 Subject: [PATCH] ci(backend-review.yml): add linter step to the backend review workflow (#625) * ci(backend-review.yml): add linter step to the backend review workflow * chore(backend-review.yml): remove prettier from lint-action configuration * chore: apply new linting workflow * chore(lint-staged.config.js): reorder lint-staged tasks for JavaScript and TypeScript files * chore(eslint): update ignorePatterns in .eslintrc.js chore(lint-action): remove prettier option in backend-review.yml chore(package.json): add lint and lint:fix scripts * chore(lint-staged.config.js): remove prettier --write command for js, jsx, ts, tsx files * chore(titleConvo.js): remove unnecessary console.log statement chore(titleConvo.js): add missing comma in options object * chore: apply linting to all files * chore(lint-staged.config.js): update lint-staged configuration to include prettier formatting --- .eslintrc.js | 57 ++++--- .github/workflows/backend-review.yml | 5 + .prettierrc.js | 2 +- api/app/bingai.js | 10 +- api/app/chatgpt-browser.js | 6 +- api/app/clients/AnthropicClient.js | 37 +++-- api/app/clients/BaseClient.js | 145 ++++++++++-------- api/app/clients/ChatGPTClient.js | 105 +++++++------ api/app/clients/GoogleClient.js | 32 ++-- api/app/clients/OpenAIClient.js | 63 ++++++-- api/app/clients/PluginsClient.js | 62 ++++---- .../clients/agents/CustomAgent/CustomAgent.js | 8 +- .../CustomAgent/initializeCustomAgent.js | 10 +- .../agents/CustomAgent/outputParser.js | 30 ++-- .../agents/Functions/FunctionsAgent.js | 22 +-- .../Functions/initializeFunctionsAgent.js | 17 +- api/app/clients/agents/index.js | 4 +- api/app/clients/index.js | 4 +- api/app/clients/prompts/instructions.js | 12 +- api/app/clients/prompts/refinePrompt.js | 4 +- api/app/clients/specs/BaseClient.test.js | 92 ++++++----- api/app/clients/specs/FakeClient.js | 30 ++-- api/app/clients/specs/OpenAIClient.test.js | 55 +++++-- api/app/clients/specs/OpenAIClient.tokens.js | 18 ++- api/app/clients/specs/PluginsClient.test.js | 24 +-- api/app/clients/tools/AIPluginTool.js | 14 +- api/app/clients/tools/DALL-E.js | 14 +- api/app/clients/tools/GoogleSearch.js | 9 +- api/app/clients/tools/HttpRequestTool.js | 5 +- api/app/clients/tools/SelfReflection.js | 7 +- api/app/clients/tools/StableDiffusion.js | 11 +- api/app/clients/tools/Wolfram.js | 2 +- api/app/clients/tools/index.js | 4 +- api/app/clients/tools/saveImageFromUrl.js | 2 +- .../tools/structured/StableDiffusion.js | 35 ++++- api/app/clients/tools/structured/Wolfram.js | 6 +- api/app/clients/tools/util/handleTools.js | 25 ++- .../clients/tools/util/handleTools.test.js | 31 ++-- api/app/clients/tools/util/index.js | 2 +- api/app/index.js | 2 +- api/app/titleConvo.js | 9 +- api/app/titleConvoBing.js | 10 +- api/jest.config.js | 2 +- api/lib/db/connectDb.js | 2 +- api/lib/db/indexSync.js | 2 +- api/lib/db/migrateDb.js | 6 +- api/lib/utils/misc.js | 2 +- api/lib/utils/reduceHits.js | 4 +- api/middleware/requireLocalAuth.js | 4 +- api/models/Config.js | 16 +- api/models/Conversation.js | 12 +- api/models/Message.js | 8 +- api/models/Preset.js | 4 +- api/models/Prompt.js | 14 +- api/models/User.js | 56 +++---- api/models/index.js | 2 +- api/models/plugins/mongoMeili.js | 14 +- api/models/schema/convoSchema.js | 24 +-- api/models/schema/defaults.js | 64 ++++---- api/models/schema/messageSchema.js | 48 +++--- api/models/schema/pluginAuthSchema.js | 8 +- api/models/schema/presetSchema.js | 12 +- api/models/schema/tokenSchema.js | 8 +- api/server/controllers/AuthController.js | 8 +- api/server/controllers/PluginController.js | 4 +- api/server/controllers/UserController.js | 2 +- .../controllers/auth/LoginController.js | 10 +- .../controllers/auth/LogoutController.js | 2 +- api/server/index.js | 4 +- api/server/routes/ask/addToCache.js | 12 +- api/server/routes/ask/anthropic.js | 26 ++-- api/server/routes/ask/askBingAI.js | 38 ++--- api/server/routes/ask/askChatGPTBrowser.js | 38 ++--- api/server/routes/ask/google.js | 30 ++-- api/server/routes/ask/gptPlugins.js | 30 ++-- api/server/routes/ask/handlers.js | 4 +- api/server/routes/ask/openAI.js | 28 ++-- api/server/routes/auth.js | 2 +- api/server/routes/config.js | 14 +- api/server/routes/endpoints.js | 4 +- api/server/routes/index.js | 2 +- api/server/routes/oauth.js | 52 +++---- api/server/routes/prompts.js | 2 +- api/server/routes/search.js | 8 +- api/server/services/PluginService.js | 6 +- api/server/services/UserService.js | 4 +- api/server/services/auth.service.js | 20 +-- api/strategies/discordStrategy.js | 6 +- api/strategies/facebookStrategy.js | 6 +- api/strategies/githubStrategy.js | 6 +- api/strategies/googleStrategy.js | 6 +- api/strategies/jwtStrategy.js | 4 +- api/strategies/localStrategy.js | 12 +- api/strategies/openidStrategy.js | 23 ++- api/strategies/validators.js | 6 +- api/utils/LoggingSystem.js | 14 +- api/utils/abortMessage.js | 2 +- api/utils/azureUtils.js | 4 +- api/utils/debug.js | 6 +- api/utils/index.js | 2 +- api/utils/sendEmail.js | 8 +- api/utils/tokens.js | 2 +- client/src/App.jsx | 4 +- client/src/components/Auth/LoginForm.tsx | 16 +- client/src/components/Auth/Registration.tsx | 34 ++-- .../components/Auth/RequestPasswordReset.tsx | 14 +- client/src/components/Auth/ResetPassword.tsx | 12 +- .../components/Auth/__tests__/Login.spec.tsx | 22 +-- .../Auth/__tests__/Registration.spec.tsx | 24 +-- .../components/Conversations/Conversation.jsx | 4 +- .../Endpoints/Anthropic/OptionHover.jsx | 4 +- .../Endpoints/Anthropic/Settings.jsx | 26 ++-- .../components/Endpoints/BingAI/Settings.jsx | 10 +- .../components/Endpoints/EditPresetDialog.jsx | 46 +++--- .../Endpoints/EndpointOptionsDialog.jsx | 4 +- .../Endpoints/EndpointOptionsPopover.jsx | 4 +- .../components/Endpoints/Google/Examples.jsx | 6 +- .../Endpoints/Google/OptionHover.jsx | 4 +- .../components/Endpoints/Google/Settings.jsx | 26 ++-- .../Endpoints/OpenAI/OptionHover.jsx | 6 +- .../components/Endpoints/OpenAI/Settings.jsx | 24 +-- .../Endpoints/Plugins/AgentSettings.jsx | 9 +- .../Endpoints/Plugins/OptionHover.jsx | 6 +- .../components/Endpoints/Plugins/Settings.jsx | 28 ++-- .../Endpoints/SaveAsPresetDialog.jsx | 8 +- .../Input/AnthropicOptions/index.jsx | 6 +- .../components/Input/BingAIOptions/index.jsx | 8 +- .../components/Input/ChatGPTOptions/index.jsx | 4 +- .../components/Input/GoogleOptions/index.jsx | 16 +- .../NewConversationMenu/EndpointItem.jsx | 6 +- .../NewConversationMenu/EndpointItems.jsx | 8 +- .../Input/NewConversationMenu/FileUpload.tsx | 4 +- .../Input/NewConversationMenu/PresetItem.jsx | 4 +- .../Input/NewConversationMenu/index.jsx | 20 +-- .../components/Input/OpenAIOptions/index.jsx | 8 +- .../components/Input/PluginsOptions/index.jsx | 16 +- .../Input/SetTokenDialog/HelpText.tsx | 2 +- .../Input/SetTokenDialog/InputWithLabel.tsx | 2 +- .../Input/SetTokenDialog/SetTokenDialog.tsx | 4 +- client/src/components/Input/SubmitButton.jsx | 2 +- .../src/components/MessageHandler/index.jsx | 34 ++-- .../components/Messages/Content/Content.jsx | 8 +- .../src/components/Messages/HoverButtons.jsx | 6 +- client/src/components/Messages/Message.jsx | 14 +- .../src/components/Messages/MessageHeader.jsx | 2 +- .../src/components/Messages/MultiMessage.jsx | 2 +- client/src/components/Messages/Plugin.jsx | 4 +- client/src/components/Messages/index.jsx | 4 +- .../Nav/ExportConversation/ExportModel.jsx | 80 +++++----- .../Nav/ExportConversation/index.jsx | 2 +- client/src/components/Nav/NavLink.jsx | 2 +- client/src/components/Nav/NavLinks.jsx | 4 +- client/src/components/Nav/SearchBar.jsx | 1 - client/src/components/Nav/Settings.jsx | 4 +- .../SettingsTabs/ClearChatsButton.spec.tsx | 6 +- .../components/Nav/SettingsTabs/General.tsx | 6 +- .../Nav/SettingsTabs/ThemeSelector.spec.tsx | 4 +- client/src/components/Nav/index.jsx | 4 +- .../Plugins/Store/PluginAuthForm.tsx | 8 +- .../Plugins/Store/PluginPagination.tsx | 2 +- .../Plugins/Store/PluginStoreDialog.tsx | 12 +- .../__tests__/PluginStoreDialog.spec.tsx | 42 ++--- client/src/components/svg/AnthropicIcon.jsx | 4 +- client/src/components/svg/GoogleIcon.jsx | 46 +++--- client/src/components/ui/AlertDialog.tsx | 10 +- client/src/components/ui/Button.tsx | 14 +- client/src/components/ui/Checkbox.tsx | 2 +- client/src/components/ui/Dialog.tsx | 12 +- .../src/components/ui/DialogTemplate.spec.tsx | 10 +- client/src/components/ui/DialogTemplate.tsx | 2 +- client/src/components/ui/Dropdown.jsx | 4 +- client/src/components/ui/DropdownMenu.tsx | 16 +- client/src/components/ui/HoverCard.tsx | 2 +- client/src/components/ui/Input.tsx | 2 +- client/src/components/ui/InputNumber.tsx | 2 +- client/src/components/ui/Label.tsx | 2 +- client/src/components/ui/ModelSelect.jsx | 2 +- .../src/components/ui/MultiSelectDropDown.jsx | 8 +- client/src/components/ui/SelectDropDown.jsx | 10 +- client/src/components/ui/Slider.tsx | 2 +- client/src/components/ui/Switch.tsx | 12 +- client/src/components/ui/Tabs.tsx | 4 +- client/src/hooks/ApiErrorBoundaryContext.tsx | 2 +- client/src/hooks/AuthContext.tsx | 20 +-- client/src/hooks/useDocumentTitle.js | 7 +- client/src/main.jsx | 2 +- client/src/routes/Chat.jsx | 4 +- client/src/routes/Root.jsx | 2 +- client/src/routes/index.jsx | 24 +-- client/src/store/conversation.js | 30 ++-- client/src/store/conversations.js | 2 +- client/src/store/endpoints.js | 10 +- client/src/store/index.js | 2 +- client/src/store/language.js | 2 +- client/src/store/preset.js | 4 +- client/src/store/search.js | 12 +- client/src/store/submission.js | 6 +- client/src/store/text.js | 2 +- client/src/store/token.js | 4 +- client/src/store/user.js | 4 +- client/src/utils/cleanupPreset.js | 16 +- client/src/utils/getDefaultConversation.js | 24 +-- client/src/utils/getIcon.jsx | 4 +- client/src/utils/handleSubmit.js | 28 ++-- client/src/utils/index.jsx | 2 +- client/src/utils/resetConvo.js | 2 +- client/vite.config.ts | 28 ++-- config/create-user.js | 12 +- config/helpers.js | 6 +- config/install.js | 14 +- config/loader.js | 15 +- config/upgrade.js | 12 +- docs/dev/eslintrc-stripped.js | 36 ++--- e2e/playwright.config.local.ts | 2 +- e2e/playwright.config.ts | 12 +- e2e/setup/authenticate.ts | 6 +- e2e/setup/global-setup.local.ts | 2 +- e2e/setup/global-setup.ts | 2 +- e2e/specs/landing.spec.js | 2 +- e2e/specs/messages.spec.js | 6 +- e2e/specs/settings.spec.js | 4 +- lint-staged.config.js | 4 +- package.json | 2 + packages/data-provider/babel.config.js | 2 +- packages/data-provider/jest.config.js | 2 +- packages/data-provider/rollup.config.js | 2 +- packages/data-provider/src/api-endpoints.ts | 20 +-- packages/data-provider/src/createPayload.ts | 4 +- packages/data-provider/src/data-service.ts | 12 +- .../data-provider/src/react-query-service.ts | 103 +++++++------ packages/data-provider/src/request.ts | 10 +- 231 files changed, 1688 insertions(+), 1526 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e3dc8484bd..d1c54c150f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,25 +4,30 @@ module.exports = { es2021: true, node: true, commonjs: true, - es6: true + es6: true, }, extends: [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:react-hooks/recommended', 'plugin:jest/recommended', - 'prettier' + 'prettier', ], + // ignorePatterns: ['packages/data-provider/types/**/*'], ignorePatterns: [ + 'client/dist/**/*', + 'client/public/**/*', + 'e2e/playwright-report/**/*', 'packages/data-provider/types/**/*', + 'packages/data-provider/dist/**/*', ], parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 'latest', sourceType: 'module', ecmaFeatures: { - jsx: true - } + jsx: true, + }, }, plugins: ['react', 'react-hooks', '@typescript-eslint'], rules: { @@ -35,13 +40,14 @@ module.exports = { code: 120, ignoreStrings: true, ignoreTemplateLiterals: true, - ignoreComments: true - } + ignoreComments: true, + }, ], 'linebreak-style': 0, 'object-curly-spacing': ['error', 'always'], 'no-trailing-spaces': 'error', - 'no-multiple-empty-lines': ['error', { 'max': 1 }], + 'no-multiple-empty-lines': ['error', { max: 1 }], + 'comma-dangle': ['error', 'always-multiline'], // "arrow-parens": [2, "as-needed", { requireForBlockBody: true }], // 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], 'no-console': 'off', @@ -52,6 +58,7 @@ module.exports = { 'no-restricted-syntax': 'off', 'react/prop-types': ['off'], 'react/display-name': ['off'], + quotes: ['error', 'single'], }, overrides: [ { @@ -59,14 +66,14 @@ module.exports = { rules: { 'no-unused-vars': 'off', // off because it conflicts with '@typescript-eslint/no-unused-vars' 'react/display-name': 'off', - '@typescript-eslint/no-unused-vars': 'warn' - } + '@typescript-eslint/no-unused-vars': 'warn', + }, }, { files: ['rollup.config.js', '.eslintrc.js', 'jest.config.js'], env: { node: true, - } + }, }, { files: [ @@ -78,29 +85,29 @@ module.exports = { '**/*.spec.jsx', '**/*.spec.ts', '**/*.spec.tsx', - 'setupTests.js' + 'setupTests.js', ], env: { jest: true, - node: true + node: true, }, rules: { 'react/display-name': 'off', 'react/prop-types': 'off', - 'react/no-unescaped-entities': 'off' - } + 'react/no-unescaped-entities': 'off', + }, }, { files: '**/*.+(ts)', parser: '@typescript-eslint/parser', parserOptions: { - project: './client/tsconfig.json' + project: './client/tsconfig.json', }, plugins: ['@typescript-eslint/eslint-plugin', 'jest'], extends: [ 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended' - ] + 'plugin:@typescript-eslint/recommended', + ], }, { files: './packages/data-provider/**/*.ts', @@ -109,11 +116,11 @@ module.exports = { files: '**/*.ts', parser: '@typescript-eslint/parser', parserOptions: { - project: './packages/data-provider/tsconfig.json' - } - } - ] - } + project: './packages/data-provider/tsconfig.json', + }, + }, + ], + }, ], settings: { react: { @@ -121,7 +128,7 @@ module.exports = { // default to "createReactClass" pragma: 'React', // Pragma to use, default to "React" fragment: 'Fragment', // Fragment to use (may be a property of ), default to "Fragment" - version: 'detect' // React version. "detect" automatically picks the version you have installed. - } - } + version: 'detect', // React version. "detect" automatically picks the version you have installed. + }, + }, }; diff --git a/.github/workflows/backend-review.yml b/.github/workflows/backend-review.yml index 07a2f85d6c..11b4b562c0 100644 --- a/.github/workflows/backend-review.yml +++ b/.github/workflows/backend-review.yml @@ -37,3 +37,8 @@ jobs: - name: Run unit tests run: cd api && npm run test:ci + + - name: Run linters + uses: wearerequired/lint-action@v2 + with: + eslint: true \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js index 7b3ddb6da1..ea7ab4bf84 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -5,7 +5,7 @@ module.exports = { semi: true, singleQuote: true, // bracketSpacing: false, - trailingComma: 'none', + trailingComma: 'all', arrowParens: 'always', embeddedLanguageFormatting: 'auto', insertPragma: false, diff --git a/api/app/bingai.js b/api/app/bingai.js index b0351120ea..1db564ceb3 100644 --- a/api/app/bingai.js +++ b/api/app/bingai.js @@ -14,11 +14,11 @@ const askBing = async ({ invocationId, toneStyle, token, - onProgress + onProgress, }) => { const { BingAIClient } = await import('@waylaidwanderer/chatgpt-api'); const store = { - store: new KeyvFile({ filename: './data/cache.json' }) + store: new KeyvFile({ filename: './data/cache.json' }), }; const bingAIClient = new BingAIClient({ @@ -30,7 +30,7 @@ const askBing = async ({ debug: false, cache: store, host: process.env.BINGAI_HOST || null, - proxy: process.env.PROXY || null + proxy: process.env.PROXY || null, }); let options = {}; @@ -46,7 +46,7 @@ const askBing = async ({ systemMessage, parentMessageId, toneStyle, - onProgress + onProgress, }; else { options = { @@ -55,7 +55,7 @@ const askBing = async ({ systemMessage, parentMessageId, toneStyle, - onProgress + onProgress, }; // don't give those parameters for new conversation diff --git a/api/app/chatgpt-browser.js b/api/app/chatgpt-browser.js index 2caf0b2917..cf98194415 100644 --- a/api/app/chatgpt-browser.js +++ b/api/app/chatgpt-browser.js @@ -10,11 +10,11 @@ const browserClient = async ({ onProgress, onEventMessage, abortController, - userId + userId, }) => { const { ChatGPTBrowserClient } = await import('@waylaidwanderer/chatgpt-api'); const store = { - store: new KeyvFile({ filename: './data/cache.json' }) + store: new KeyvFile({ filename: './data/cache.json' }), }; const clientOptions = { @@ -27,7 +27,7 @@ const browserClient = async ({ model: model, debug: false, proxy: process.env.PROXY || null, - user: userId + user: userId, }; const client = new ChatGPTBrowserClient(clientOptions, store); diff --git a/api/app/clients/AnthropicClient.js b/api/app/clients/AnthropicClient.js index 280318a241..cf9571c69b 100644 --- a/api/app/clients/AnthropicClient.js +++ b/api/app/clients/AnthropicClient.js @@ -3,7 +3,7 @@ const Keyv = require('keyv'); const BaseClient = require('./BaseClient'); const { encoding_for_model: encodingForModel, - get_encoding: getEncoding + get_encoding: getEncoding, } = require('@dqbd/tiktoken'); const Anthropic = require('@anthropic-ai/sdk'); @@ -13,9 +13,8 @@ const AI_PROMPT = '\n\nAssistant:'; const tokenizersCache = {}; class AnthropicClient extends BaseClient { - constructor(apiKey, options = {}, cacheOptions = {}) { - super(apiKey, options, cacheOptions) + super(apiKey, options, cacheOptions); cacheOptions.namespace = cacheOptions.namespace || 'anthropic'; this.conversationsCache = new Keyv(cacheOptions); this.apiKey = apiKey || process.env.ANTHROPIC_API_KEY; @@ -30,7 +29,7 @@ class AnthropicClient extends BaseClient { // nested options aren't spread properly, so we need to do this manually this.options.modelOptions = { ...this.options.modelOptions, - ...options.modelOptions + ...options.modelOptions, }; delete options.modelOptions; // now we can merge options @@ -50,7 +49,7 @@ class AnthropicClient extends BaseClient { temperature: typeof modelOptions.temperature === 'undefined' ? 0.7 : modelOptions.temperature, // 0 - 1, 0.7 is recommended topP: typeof modelOptions.topP === 'undefined' ? 0.7 : modelOptions.topP, // 0 - 1, default: 0.7 topK: typeof modelOptions.topK === 'undefined' ? 40 : modelOptions.topK, // 1-40, default: 40 - stop: modelOptions.stop // no stop method for now + stop: modelOptions.stop, // no stop method for now }; this.maxContextTokens = this.options.maxContextTokens || 99999; @@ -62,7 +61,7 @@ class AnthropicClient extends BaseClient { throw new Error( `maxPromptTokens + maxOutputTokens (${this.maxPromptTokens} + ${this.maxResponseTokens} = ${ this.maxPromptTokens + this.maxResponseTokens - }) must be less than or equal to maxContextTokens (${this.maxContextTokens})` + }) must be less than or equal to maxContextTokens (${this.maxContextTokens})`, ); } @@ -85,18 +84,17 @@ class AnthropicClient extends BaseClient { } getClient() { - if(this.options.reverseProxyUrl) { + if (this.options.reverseProxyUrl) { return new Anthropic({ apiKey: this.apiKey, - baseURL: this.options.reverseProxyUrl + baseURL: this.options.reverseProxyUrl, }); - } - else { + } else { return new Anthropic({ apiKey: this.apiKey, }); } - }; + } async buildMessages(messages, parentMessageId) { const orderedMessages = this.constructor.getMessagesForConversation(messages, parentMessageId); @@ -106,7 +104,7 @@ class AnthropicClient extends BaseClient { const formattedMessages = orderedMessages.map((message) => ({ author: message.isCreatedByUser ? this.userLabel : this.assistantLabel, - content: message?.content ?? message.text + content: message?.content ?? message.text, })); let identityPrefix = ''; @@ -169,7 +167,9 @@ class AnthropicClient extends BaseClient { if (newTokenCount > maxTokenCount) { if (!promptBody) { // This is the first message, so we can't add it. Just throw an error. - throw new Error(`Prompt is too long. Max token count is ${maxTokenCount}, but prompt is ${newTokenCount} tokens long.`); + throw new Error( + `Prompt is too long. Max token count is ${maxTokenCount}, but prompt is ${newTokenCount} tokens long.`, + ); } // Otherwise, ths message would put us over the token limit, so don't add it. @@ -183,7 +183,7 @@ class AnthropicClient extends BaseClient { promptBody = newPromptBody; currentTokenCount = newTokenCount; // wait for next tick to avoid blocking the event loop - await new Promise(resolve => setImmediate(resolve)); + await new Promise((resolve) => setImmediate(resolve)); return buildPromptBody(); } return true; @@ -202,7 +202,10 @@ class AnthropicClient extends BaseClient { currentTokenCount += 2; // Use up to `this.maxContextTokens` tokens (prompt + response), but try to leave `this.maxTokens` tokens for the response. - this.modelOptions.maxOutputTokens = Math.min(this.maxContextTokens - currentTokenCount, this.maxResponseTokens); + this.modelOptions.maxOutputTokens = Math.min( + this.maxContextTokens - currentTokenCount, + this.maxResponseTokens, + ); return { prompt, context }; } @@ -243,7 +246,7 @@ class AnthropicClient extends BaseClient { stream: this.modelOptions.stream || true, max_tokens_to_sample: this.modelOptions.maxOutputTokens || 1500, metadata, - ...modelOptions + ...modelOptions, }; if (this.options.debug) { console.log('AnthropicClient: requestOptions'); @@ -289,7 +292,7 @@ class AnthropicClient extends BaseClient { return { promptPrefix: this.options.promptPrefix, modelLabel: this.options.modelLabel, - ...this.modelOptions + ...this.modelOptions, }; } diff --git a/api/app/clients/BaseClient.js b/api/app/clients/BaseClient.js index 291753666f..baaa0990d3 100644 --- a/api/app/clients/BaseClient.js +++ b/api/app/clients/BaseClient.js @@ -14,7 +14,7 @@ class BaseClient { this.currentDateString = new Date().toLocaleDateString('en-us', { year: 'numeric', month: 'long', - day: 'numeric' + day: 'numeric', }); } @@ -58,7 +58,7 @@ class BaseClient { const responseMessageId = crypto.randomUUID(); const saveOptions = this.getSaveOptions(); this.abortController = opts.abortController || new AbortController(); - this.currentMessages = await this.loadHistory(conversationId, parentMessageId) ?? []; + this.currentMessages = (await this.loadHistory(conversationId, parentMessageId)) ?? []; return { ...opts, @@ -78,20 +78,14 @@ class BaseClient { conversationId, sender: 'User', text, - isCreatedByUser: true + isCreatedByUser: true, }; return userMessage; } async handleStartMethods(message, opts) { - const { - user, - conversationId, - parentMessageId, - userMessageId, - responseMessageId, - saveOptions, - } = await this.setMessageOptions(opts); + const { user, conversationId, parentMessageId, userMessageId, responseMessageId, saveOptions } = + await this.setMessageOptions(opts); const userMessage = this.createUserMessage({ messageId: userMessageId, @@ -104,7 +98,7 @@ class BaseClient { opts.getIds({ userMessage, conversationId, - responseMessageId + responseMessageId, }); } @@ -189,24 +183,32 @@ class BaseClient { async refineMessages(messagesToRefine, remainingContextTokens) { const model = new ChatOpenAI({ temperature: 0 }); - const chain = loadSummarizationChain(model, { type: 'refine', verbose: this.options.debug, refinePrompt }); + const chain = loadSummarizationChain(model, { + type: 'refine', + verbose: this.options.debug, + refinePrompt, + }); const splitter = new RecursiveCharacterTextSplitter({ chunkSize: 1500, chunkOverlap: 100, }); - const userMessages = this.concatenateMessages(messagesToRefine.filter(m => m.role === 'user')); - const assistantMessages = this.concatenateMessages(messagesToRefine.filter(m => m.role !== 'user')); - const userDocs = await splitter.createDocuments([userMessages],[],{ + const userMessages = this.concatenateMessages( + messagesToRefine.filter((m) => m.role === 'user'), + ); + const assistantMessages = this.concatenateMessages( + messagesToRefine.filter((m) => m.role !== 'user'), + ); + const userDocs = await splitter.createDocuments([userMessages], [], { chunkHeader: 'DOCUMENT NAME: User Message\n\n---\n\n', appendChunkOverlapHeader: true, }); - const assistantDocs = await splitter.createDocuments([assistantMessages],[],{ + const assistantDocs = await splitter.createDocuments([assistantMessages], [], { chunkHeader: 'DOCUMENT NAME: Assistant Message\n\n---\n\n', appendChunkOverlapHeader: true, }); // const chunkSize = Math.round(concatenatedMessages.length / 512); const input_documents = userDocs.concat(assistantDocs); - if (this.options.debug ) { + if (this.options.debug) { console.debug('Refining messages...'); } try { @@ -219,11 +221,15 @@ class BaseClient { role: 'assistant', content: res.output_text, tokenCount: this.getTokenCount(res.output_text), - } + }; - if (this.options.debug ) { + if (this.options.debug) { console.debug('Refined messages', refinedMessage); - console.debug(`remainingContextTokens: ${remainingContextTokens}, after refining: ${remainingContextTokens - refinedMessage.tokenCount}`); + console.debug( + `remainingContextTokens: ${remainingContextTokens}, after refining: ${ + remainingContextTokens - refinedMessage.tokenCount + }`, + ); } return refinedMessage; @@ -235,15 +241,15 @@ class BaseClient { } /** - * This method processes an array of messages and returns a context of messages that fit within a token limit. - * It iterates over the messages from newest to oldest, adding them to the context until the token limit is reached. - * If the token limit would be exceeded by adding a message, that message and possibly the previous one are added to a separate array of messages to refine. - * The method uses `push` and `pop` operations for efficient array manipulation, and reverses the arrays at the end to maintain the original order of the messages. - * The method also includes a mechanism to avoid blocking the event loop by waiting for the next tick after each iteration. - * - * @param {Array} messages - An array of messages, each with a `tokenCount` property. The messages should be ordered from oldest to newest. - * @returns {Object} An object with three properties: `context`, `remainingContextTokens`, and `messagesToRefine`. `context` is an array of messages that fit within the token limit. `remainingContextTokens` is the number of tokens remaining within the limit after adding the messages to the context. `messagesToRefine` is an array of messages that were not added to the context because they would have exceeded the token limit. - */ + * This method processes an array of messages and returns a context of messages that fit within a token limit. + * It iterates over the messages from newest to oldest, adding them to the context until the token limit is reached. + * If the token limit would be exceeded by adding a message, that message and possibly the previous one are added to a separate array of messages to refine. + * The method uses `push` and `pop` operations for efficient array manipulation, and reverses the arrays at the end to maintain the original order of the messages. + * The method also includes a mechanism to avoid blocking the event loop by waiting for the next tick after each iteration. + * + * @param {Array} messages - An array of messages, each with a `tokenCount` property. The messages should be ordered from oldest to newest. + * @returns {Object} An object with three properties: `context`, `remainingContextTokens`, and `messagesToRefine`. `context` is an array of messages that fit within the token limit. `remainingContextTokens` is the number of tokens remaining within the limit after adding the messages to the context. `messagesToRefine` is an array of messages that were not added to the context because they would have exceeded the token limit. + */ async getMessagesWithinTokenLimit(messages) { let currentTokenCount = 0; let context = []; @@ -282,26 +288,22 @@ class BaseClient { context.push(message); currentTokenCount = newTokenCount; remainingContextTokens = this.maxContextTokens - currentTokenCount; - await new Promise(resolve => setImmediate(resolve)); + await new Promise((resolve) => setImmediate(resolve)); } return { context: context.reverse(), remainingContextTokens, messagesToRefine: messagesToRefine.reverse(), - refineIndex + refineIndex, }; } async handleContextStrategy({ instructions, orderedMessages, formattedMessages }) { let payload = this.addInstructions(formattedMessages, instructions); let orderedWithInstructions = this.addInstructions(orderedMessages, instructions); - let { - context, - remainingContextTokens, - messagesToRefine, - refineIndex - } = await this.getMessagesWithinTokenLimit(payload); + let { context, remainingContextTokens, messagesToRefine, refineIndex } = + await this.getMessagesWithinTokenLimit(payload); payload = context; let refinedMessage; @@ -325,8 +327,14 @@ class BaseClient { if (this.options.debug) { console.debug('<---------------------------------DIFF--------------------------------->'); - console.debug(`Difference between payload (${payload.length}) and orderedWithInstructions (${orderedWithInstructions.length}): ${diff}`); - console.debug('remainingContextTokens, this.maxContextTokens (1/2)', remainingContextTokens, this.maxContextTokens); + console.debug( + `Difference between payload (${payload.length}) and orderedWithInstructions (${orderedWithInstructions.length}): ${diff}`, + ); + console.debug( + 'remainingContextTokens, this.maxContextTokens (1/2)', + remainingContextTokens, + this.maxContextTokens, + ); } // If the difference is positive, slice the orderedWithInstructions array @@ -341,7 +349,11 @@ class BaseClient { } if (this.options.debug) { - console.debug('remainingContextTokens, this.maxContextTokens (2/2)', remainingContextTokens, this.maxContextTokens); + console.debug( + 'remainingContextTokens, this.maxContextTokens (2/2)', + remainingContextTokens, + this.maxContextTokens, + ); } let tokenCountMap = orderedWithInstructions.reduce((map, message, index) => { @@ -370,20 +382,19 @@ class BaseClient { } async sendMessage(message, opts = {}) { - const { - user, - conversationId, - responseMessageId, - saveOptions, - userMessage, - } = await this.handleStartMethods(message, opts); + const { user, conversationId, responseMessageId, saveOptions, userMessage } = + await this.handleStartMethods(message, opts); this.user = user; // It's not necessary to push to currentMessages // depending on subclass implementation of handling messages this.currentMessages.push(userMessage); - let { prompt: payload, tokenCountMap, promptTokens } = await this.buildMessages( + let { + prompt: payload, + tokenCountMap, + promptTokens, + } = await this.buildMessages( this.currentMessages, // When the userMessage is pushed to currentMessages, the parentMessage is the userMessageId. // this only matters when buildMessages is utilizing the parentMessageId, and may vary on implementation @@ -397,7 +408,7 @@ class BaseClient { } if (tokenCountMap) { - console.dir(tokenCountMap, { depth: null }) + console.dir(tokenCountMap, { depth: null }); if (tokenCountMap[userMessage.messageId]) { userMessage.tokenCount = tokenCountMap[userMessage.messageId]; console.log('userMessage.tokenCount', userMessage.tokenCount); @@ -461,7 +472,7 @@ class BaseClient { await saveConvo(user, { conversationId: message.conversationId, endpoint: this.options.endpoint, - ...endpointOptions + ...endpointOptions, }); } @@ -470,12 +481,12 @@ class BaseClient { } /** - * Iterate through messages, building an array based on the parentMessageId. - * Each message has an id and a parentMessageId. The parentMessageId is the id of the message that this message is a reply to. - * @param messages - * @param parentMessageId - * @returns {*[]} An array containing the messages in the order they should be displayed, starting with the root message. - */ + * Iterate through messages, building an array based on the parentMessageId. + * Each message has an id and a parentMessageId. The parentMessageId is the id of the message that this message is a reply to. + * @param messages + * @param parentMessageId + * @returns {*[]} An array containing the messages in the order they should be displayed, starting with the root message. + */ static getMessagesForConversation(messages, parentMessageId, mapMethod = null) { if (!messages || messages.length === 0) { return []; @@ -484,7 +495,7 @@ class BaseClient { const orderedMessages = []; let currentMessageId = parentMessageId; while (currentMessageId) { - const message = messages.find(msg => { + const message = messages.find((msg) => { const messageId = msg.messageId ?? msg.id; return messageId === currentMessageId; }); @@ -503,13 +514,13 @@ class BaseClient { } /** - * Algorithm adapted from "6. Counting tokens for chat API calls" of - * https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb - * - * An additional 2 tokens need to be added for metadata after all messages have been counted. - * - * @param {*} message - */ + * Algorithm adapted from "6. Counting tokens for chat API calls" of + * https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb + * + * An additional 2 tokens need to be added for metadata after all messages have been counted. + * + * @param {*} message + */ getTokenCountForMessage(message) { let tokensPerMessage; let nameAdjustment; @@ -534,7 +545,7 @@ class BaseClient { const numTokens = this.getTokenCount(value); // Adjust by `nameAdjustment` tokens if the property key is 'name' - const adjustment = (key === 'name') ? nameAdjustment : 0; + const adjustment = key === 'name' ? nameAdjustment : 0; return numTokens + adjustment; }); @@ -547,4 +558,4 @@ class BaseClient { } } -module.exports = BaseClient; \ No newline at end of file +module.exports = BaseClient; diff --git a/api/app/clients/ChatGPTClient.js b/api/app/clients/ChatGPTClient.js index 81dfa2ee49..72715669e6 100644 --- a/api/app/clients/ChatGPTClient.js +++ b/api/app/clients/ChatGPTClient.js @@ -1,6 +1,9 @@ const crypto = require('crypto'); const Keyv = require('keyv'); -const { encoding_for_model: encodingForModel, get_encoding: getEncoding } = require('@dqbd/tiktoken'); +const { + encoding_for_model: encodingForModel, + get_encoding: getEncoding, +} = require('@dqbd/tiktoken'); const { fetchEventSource } = require('@waylaidwanderer/fetch-event-source'); const { Agent, ProxyAgent } = require('undici'); const BaseClient = require('./BaseClient'); @@ -9,11 +12,7 @@ const CHATGPT_MODEL = 'gpt-3.5-turbo'; const tokenizersCache = {}; class ChatGPTClient extends BaseClient { - constructor( - apiKey, - options = {}, - cacheOptions = {}, - ) { + constructor(apiKey, options = {}, cacheOptions = {}) { super(apiKey, options, cacheOptions); cacheOptions.namespace = cacheOptions.namespace || 'chatgpt'; @@ -49,13 +48,16 @@ class ChatGPTClient extends BaseClient { model: modelOptions.model || CHATGPT_MODEL, temperature: typeof modelOptions.temperature === 'undefined' ? 0.8 : modelOptions.temperature, top_p: typeof modelOptions.top_p === 'undefined' ? 1 : modelOptions.top_p, - presence_penalty: typeof modelOptions.presence_penalty === 'undefined' ? 1 : modelOptions.presence_penalty, + presence_penalty: + typeof modelOptions.presence_penalty === 'undefined' ? 1 : modelOptions.presence_penalty, stop: modelOptions.stop, }; this.isChatGptModel = this.modelOptions.model.startsWith('gpt-'); const { isChatGptModel } = this; - this.isUnofficialChatGptModel = this.modelOptions.model.startsWith('text-chat') || this.modelOptions.model.startsWith('text-davinci-002-render'); + this.isUnofficialChatGptModel = + this.modelOptions.model.startsWith('text-chat') || + this.modelOptions.model.startsWith('text-davinci-002-render'); const { isUnofficialChatGptModel } = this; // Davinci models have a max context length of 4097 tokens. @@ -64,10 +66,15 @@ class ChatGPTClient extends BaseClient { // The max prompt tokens is determined by the max context tokens minus the max response tokens. // Earlier messages will be dropped until the prompt is within the limit. this.maxResponseTokens = this.modelOptions.max_tokens || 1024; - this.maxPromptTokens = this.options.maxPromptTokens || (this.maxContextTokens - this.maxResponseTokens); + this.maxPromptTokens = + this.options.maxPromptTokens || this.maxContextTokens - this.maxResponseTokens; if (this.maxPromptTokens + this.maxResponseTokens > this.maxContextTokens) { - throw new Error(`maxPromptTokens + max_tokens (${this.maxPromptTokens} + ${this.maxResponseTokens} = ${this.maxPromptTokens + this.maxResponseTokens}) must be less than or equal to maxContextTokens (${this.maxContextTokens})`); + throw new Error( + `maxPromptTokens + max_tokens (${this.maxPromptTokens} + ${this.maxResponseTokens} = ${ + this.maxPromptTokens + this.maxResponseTokens + }) must be less than or equal to maxContextTokens (${this.maxContextTokens})`, + ); } this.userLabel = this.options.userLabel || 'User'; @@ -249,13 +256,10 @@ class ChatGPTClient extends BaseClient { } }); } - const response = await fetch( - url, - { - ...opts, - signal: abortController.signal, - }, - ); + const response = await fetch(url, { + ...opts, + signal: abortController.signal, + }); if (response.status !== 200) { const body = await response.text(); const error = new Error(`Failed to send message. HTTP ${response.status} - ${body}`); @@ -299,10 +303,7 @@ ${botMessage.message} .trim(); } - async sendMessage( - message, - opts = {}, - ) { + async sendMessage(message, opts = {}) { if (opts.clientOptions && typeof opts.clientOptions === 'object') { this.setOptions(opts.clientOptions); } @@ -310,9 +311,10 @@ ${botMessage.message} const conversationId = opts.conversationId || crypto.randomUUID(); const parentMessageId = opts.parentMessageId || crypto.randomUUID(); - let conversation = typeof opts.conversation === 'object' - ? opts.conversation - : await this.conversationsCache.get(conversationId); + let conversation = + typeof opts.conversation === 'object' + ? opts.conversation + : await this.conversationsCache.get(conversationId); let isNewConversation = false; if (!conversation) { @@ -357,7 +359,9 @@ ${botMessage.message} if (progressMessage === '[DONE]') { return; } - const token = this.isChatGptModel ? progressMessage.choices[0].delta.content : progressMessage.choices[0].text; + const token = this.isChatGptModel + ? progressMessage.choices[0].delta.content + : progressMessage.choices[0].text; // first event's delta content is always undefined if (!token) { return; @@ -437,10 +441,11 @@ ${botMessage.message} } promptPrefix = `${this.startToken}Instructions:\n${promptPrefix}`; } else { - const currentDateString = new Date().toLocaleDateString( - 'en-us', - { year: 'numeric', month: 'long', day: 'numeric' }, - ); + const currentDateString = new Date().toLocaleDateString('en-us', { + year: 'numeric', + month: 'long', + day: 'numeric', + }); promptPrefix = `${this.startToken}Instructions:\nYou are ChatGPT, a large language model trained by OpenAI. Respond conversationally.\nCurrent date: ${currentDateString}${this.endToken}\n\n`; } @@ -459,7 +464,9 @@ ${botMessage.message} let currentTokenCount; if (isChatGptModel) { - currentTokenCount = this.getTokenCountForMessage(instructionsPayload) + this.getTokenCountForMessage(messagePayload); + currentTokenCount = + this.getTokenCountForMessage(instructionsPayload) + + this.getTokenCountForMessage(messagePayload); } else { currentTokenCount = this.getTokenCount(`${promptPrefix}${promptSuffix}`); } @@ -473,8 +480,13 @@ ${botMessage.message} const buildPromptBody = async () => { if (currentTokenCount < maxTokenCount && orderedMessages.length > 0) { const message = orderedMessages.pop(); - const roleLabel = message?.isCreatedByUser || message?.role?.toLowerCase() === 'user' ? this.userLabel : this.chatGptLabel; - const messageString = `${this.startToken}${roleLabel}:\n${message?.text ?? message?.message}${this.endToken}\n`; + const roleLabel = + message?.isCreatedByUser || message?.role?.toLowerCase() === 'user' + ? this.userLabel + : this.chatGptLabel; + const messageString = `${this.startToken}${roleLabel}:\n${ + message?.text ?? message?.message + }${this.endToken}\n`; let newPromptBody; if (promptBody || isChatGptModel) { newPromptBody = `${messageString}${promptBody}`; @@ -496,12 +508,14 @@ ${botMessage.message} return false; } // This is the first message, so we can't add it. Just throw an error. - throw new Error(`Prompt is too long. Max token count is ${maxTokenCount}, but prompt is ${newTokenCount} tokens long.`); + throw new Error( + `Prompt is too long. Max token count is ${maxTokenCount}, but prompt is ${newTokenCount} tokens long.`, + ); } promptBody = newPromptBody; currentTokenCount = newTokenCount; // wait for next tick to avoid blocking the event loop - await new Promise(resolve => setImmediate(resolve)); + await new Promise((resolve) => setImmediate(resolve)); return buildPromptBody(); } return true; @@ -517,7 +531,10 @@ ${botMessage.message} } // Use up to `this.maxContextTokens` tokens (prompt + response), but try to leave `this.maxTokens` tokens for the response. - this.modelOptions.max_tokens = Math.min(this.maxContextTokens - currentTokenCount, this.maxResponseTokens); + this.modelOptions.max_tokens = Math.min( + this.maxContextTokens - currentTokenCount, + this.maxResponseTokens, + ); if (this.options.debug) { console.debug(`Prompt : ${prompt}`); @@ -534,13 +551,13 @@ ${botMessage.message} } /** - * Algorithm adapted from "6. Counting tokens for chat API calls" of - * https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb - * - * An additional 2 tokens need to be added for metadata after all messages have been counted. - * - * @param {*} message - */ + * Algorithm adapted from "6. Counting tokens for chat API calls" of + * https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb + * + * An additional 2 tokens need to be added for metadata after all messages have been counted. + * + * @param {*} message + */ getTokenCountForMessage(message) { let tokensPerMessage; let nameAdjustment; @@ -558,7 +575,7 @@ ${botMessage.message} const numTokens = this.getTokenCount(value); // Adjust by `nameAdjustment` tokens if the property key is 'name' - const adjustment = (key === 'name') ? nameAdjustment : 0; + const adjustment = key === 'name' ? nameAdjustment : 0; return numTokens + adjustment; }); @@ -567,4 +584,4 @@ ${botMessage.message} } } -module.exports = ChatGPTClient; \ No newline at end of file +module.exports = ChatGPTClient; diff --git a/api/app/clients/GoogleClient.js b/api/app/clients/GoogleClient.js index 932a031a64..2fad6ca97f 100644 --- a/api/app/clients/GoogleClient.js +++ b/api/app/clients/GoogleClient.js @@ -3,7 +3,7 @@ const { google } = require('googleapis'); const { Agent, ProxyAgent } = require('undici'); const { encoding_for_model: encodingForModel, - get_encoding: getEncoding + get_encoding: getEncoding, } = require('@dqbd/tiktoken'); const tokenizersCache = {}; @@ -43,20 +43,20 @@ class GoogleClient extends BaseClient { // nested options aren't spread properly, so we need to do this manually this.options.modelOptions = { ...this.options.modelOptions, - ...options.modelOptions + ...options.modelOptions, }; delete options.modelOptions; // now we can merge options this.options = { ...this.options, - ...options + ...options, }; } else { this.options = options; } this.options.examples = this.options.examples.filter( - (obj) => obj.input.content !== '' && obj.output.content !== '' + (obj) => obj.input.content !== '' && obj.output.content !== '', ); const modelOptions = this.options.modelOptions || {}; @@ -66,7 +66,7 @@ class GoogleClient extends BaseClient { model: modelOptions.model || 'chat-bison', temperature: typeof modelOptions.temperature === 'undefined' ? 0.2 : modelOptions.temperature, // 0 - 1, 0.2 is recommended topP: typeof modelOptions.topP === 'undefined' ? 0.95 : modelOptions.topP, // 0 - 1, default: 0.95 - topK: typeof modelOptions.topK === 'undefined' ? 40 : modelOptions.topK // 1-40, default: 40 + topK: typeof modelOptions.topK === 'undefined' ? 40 : modelOptions.topK, // 1-40, default: 40 // stop: modelOptions.stop // no stop method for now }; @@ -86,7 +86,7 @@ class GoogleClient extends BaseClient { throw new Error( `maxPromptTokens + maxOutputTokens (${this.maxPromptTokens} + ${this.maxResponseTokens} = ${ this.maxPromptTokens + this.maxResponseTokens - }) must be less than or equal to maxContextTokens (${this.maxContextTokens})` + }) must be less than or equal to maxContextTokens (${this.maxContextTokens})`, ); } @@ -105,7 +105,7 @@ class GoogleClient extends BaseClient { this.endToken = '<|im_end|>'; this.gptEncoder = this.constructor.getTokenizer('text-davinci-003', true, { '<|im_start|>': 100264, - '<|im_end|>': 100265 + '<|im_end|>': 100265, }); } else { // Previously I was trying to use "<|endoftext|>" but there seems to be some bug with OpenAI's token counting @@ -143,7 +143,7 @@ class GoogleClient extends BaseClient { getMessageMapMethod() { return ((message) => ({ author: message?.author ?? (message.isCreatedByUser ? this.userLabel : this.modelLabel), - content: message?.content ?? message.text + content: message?.content ?? message.text, })).bind(this); } @@ -153,9 +153,9 @@ class GoogleClient extends BaseClient { instances: [ { messages: formattedMessages, - } + }, ], - parameters: this.options.modelOptions + parameters: this.options.modelOptions, }; if (this.options.promptPrefix) { @@ -170,8 +170,8 @@ class GoogleClient extends BaseClient { if (this.isTextModel) { payload.instances = [ { - prompt: messages[messages.length -1].content - } + prompt: messages[messages.length - 1].content, + }, ]; } @@ -199,9 +199,9 @@ class GoogleClient extends BaseClient { method: 'POST', agent: new Agent({ bodyTimeout: 0, - headersTimeout: 0 + headersTimeout: 0, }), - signal: abortController.signal + signal: abortController.signal, }; if (this.options.proxy) { @@ -218,7 +218,7 @@ class GoogleClient extends BaseClient { return { promptPrefix: this.options.promptPrefix, modelLabel: this.options.modelLabel, - ...this.modelOptions + ...this.modelOptions, }; } @@ -239,7 +239,7 @@ class GoogleClient extends BaseClient { ''; if (blocked === true) { reply = `Google blocked a proper response to your message:\n${JSON.stringify( - result.predictions[0].safetyAttributes + result.predictions[0].safetyAttributes, )}${reply.length > 0 ? `\nAI Response:\n${reply}` : ''}`; } if (this.options.debug) { diff --git a/api/app/clients/OpenAIClient.js b/api/app/clients/OpenAIClient.js index de7d646f3f..97f7851071 100644 --- a/api/app/clients/OpenAIClient.js +++ b/api/app/clients/OpenAIClient.js @@ -1,6 +1,9 @@ const BaseClient = require('./BaseClient'); const ChatGPTClient = require('./ChatGPTClient'); -const { encoding_for_model: encodingForModel, get_encoding: getEncoding } = require('@dqbd/tiktoken'); +const { + encoding_for_model: encodingForModel, + get_encoding: getEncoding, +} = require('@dqbd/tiktoken'); const { maxTokensMap, genAzureChatCompletion } = require('../../utils'); const tokenizersCache = {}; @@ -12,7 +15,9 @@ class OpenAIClient extends BaseClient { this.buildPrompt = this.ChatGPTClient.buildPrompt.bind(this); this.getCompletion = this.ChatGPTClient.getCompletion.bind(this); this.sender = options.sender ?? 'ChatGPT'; - this.contextStrategy = options.contextStrategy ? options.contextStrategy.toLowerCase() : 'discard'; + this.contextStrategy = options.contextStrategy + ? options.contextStrategy.toLowerCase() + : 'discard'; this.shouldRefineContext = this.contextStrategy === 'refine'; this.azure = options.azure || false; if (this.azure) { @@ -45,27 +50,39 @@ class OpenAIClient extends BaseClient { this.modelOptions = { ...modelOptions, model: modelOptions.model || 'gpt-3.5-turbo', - temperature: typeof modelOptions.temperature === 'undefined' ? 0.8 : modelOptions.temperature, + temperature: + typeof modelOptions.temperature === 'undefined' ? 0.8 : modelOptions.temperature, top_p: typeof modelOptions.top_p === 'undefined' ? 1 : modelOptions.top_p, - presence_penalty: typeof modelOptions.presence_penalty === 'undefined' ? 1 : modelOptions.presence_penalty, + presence_penalty: + typeof modelOptions.presence_penalty === 'undefined' ? 1 : modelOptions.presence_penalty, stop: modelOptions.stop, }; } - this.isChatCompletion = this.options.reverseProxyUrl || this.options.localAI || this.modelOptions.model.startsWith('gpt-'); + this.isChatCompletion = + this.options.reverseProxyUrl || + this.options.localAI || + this.modelOptions.model.startsWith('gpt-'); this.isChatGptModel = this.isChatCompletion; if (this.modelOptions.model === 'text-davinci-003') { this.isChatCompletion = false; this.isChatGptModel = false; } const { isChatGptModel } = this; - this.isUnofficialChatGptModel = this.modelOptions.model.startsWith('text-chat') || this.modelOptions.model.startsWith('text-davinci-002-render'); + this.isUnofficialChatGptModel = + this.modelOptions.model.startsWith('text-chat') || + this.modelOptions.model.startsWith('text-davinci-002-render'); this.maxContextTokens = maxTokensMap[this.modelOptions.model] ?? 4095; // 1 less than maximum this.maxResponseTokens = this.modelOptions.max_tokens || 1024; - this.maxPromptTokens = this.options.maxPromptTokens || (this.maxContextTokens - this.maxResponseTokens); + this.maxPromptTokens = + this.options.maxPromptTokens || this.maxContextTokens - this.maxResponseTokens; if (this.maxPromptTokens + this.maxResponseTokens > this.maxContextTokens) { - throw new Error(`maxPromptTokens + max_tokens (${this.maxPromptTokens} + ${this.maxResponseTokens} = ${this.maxPromptTokens + this.maxResponseTokens}) must be less than or equal to maxContextTokens (${this.maxContextTokens})`); + throw new Error( + `maxPromptTokens + max_tokens (${this.maxPromptTokens} + ${this.maxResponseTokens} = ${ + this.maxPromptTokens + this.maxResponseTokens + }) must be less than or equal to maxContextTokens (${this.maxContextTokens})`, + ); } this.userLabel = this.options.userLabel || 'User'; @@ -185,7 +202,7 @@ class OpenAIClient extends BaseClient { return { chatGptLabel: this.options.chatGptLabel, promptPrefix: this.options.promptPrefix, - ...this.modelOptions + ...this.modelOptions, }; } @@ -197,9 +214,16 @@ class OpenAIClient extends BaseClient { }; } - async buildMessages(messages, parentMessageId, { isChatCompletion = false, promptPrefix = null }) { + async buildMessages( + messages, + parentMessageId, + { isChatCompletion = false, promptPrefix = null }, + ) { if (!isChatCompletion) { - return await this.buildPrompt(messages, parentMessageId, { isChatGptModel: isChatCompletion, promptPrefix }); + return await this.buildPrompt(messages, parentMessageId, { + isChatGptModel: isChatCompletion, + promptPrefix, + }); } let payload; @@ -214,7 +238,7 @@ class OpenAIClient extends BaseClient { instructions = { role: 'system', name: 'instructions', - content: promptPrefix + content: promptPrefix, }; if (this.contextStrategy) { @@ -236,7 +260,8 @@ class OpenAIClient extends BaseClient { } if (this.contextStrategy) { - formattedMessage.tokenCount = message.tokenCount ?? this.getTokenCountForMessage(formattedMessage); + formattedMessage.tokenCount = + message.tokenCount ?? this.getTokenCountForMessage(formattedMessage); } return formattedMessage; @@ -244,8 +269,11 @@ class OpenAIClient extends BaseClient { // TODO: need to handle interleaving instructions better if (this.contextStrategy) { - ({ payload, tokenCountMap, promptTokens, messages } = - await this.handleContextStrategy({ instructions, orderedMessages, formattedMessages })); + ({ payload, tokenCountMap, promptTokens, messages } = await this.handleContextStrategy({ + instructions, + orderedMessages, + formattedMessages, + })); } const result = { @@ -272,8 +300,9 @@ class OpenAIClient extends BaseClient { if (progressMessage === '[DONE]') { return; } - const token = - this.isChatCompletion ? progressMessage.choices?.[0]?.delta?.content : progressMessage.choices?.[0]?.text; + const token = this.isChatCompletion + ? progressMessage.choices?.[0]?.delta?.content + : progressMessage.choices?.[0]?.text; // first event's delta content is always undefined if (!token) { return; diff --git a/api/app/clients/PluginsClient.js b/api/app/clients/PluginsClient.js index fc95196d4e..4ccf1435e1 100644 --- a/api/app/clients/PluginsClient.js +++ b/api/app/clients/PluginsClient.js @@ -5,11 +5,7 @@ const { initializeCustomAgent, initializeFunctionsAgent } = require('./agents/') const { loadTools } = require('./tools/util'); const { SelfReflectionTool } = require('./tools/'); const { HumanChatMessage, AIChatMessage } = require('langchain/schema'); -const { - instructions, - imageInstructions, - errorInstructions, -} = require('./prompts/instructions'); +const { instructions, imageInstructions, errorInstructions } = require('./prompts/instructions'); class PluginsClient extends OpenAIClient { constructor(apiKey, options = {}) { @@ -28,11 +24,13 @@ class PluginsClient extends OpenAIClient { if (actions[0]?.action && this.functionsAgent) { actions = actions.map((step) => ({ - log: `Action: ${step.action?.tool || ''}\nInput: ${JSON.stringify(step.action?.toolInput) || ''}\nObservation: ${step.observation}` + log: `Action: ${step.action?.tool || ''}\nInput: ${ + JSON.stringify(step.action?.toolInput) || '' + }\nObservation: ${step.observation}`, })); } else if (actions[0]?.action) { actions = actions.map((step) => ({ - log: `${step.action.log}\nObservation: ${step.observation}` + log: `${step.action.log}\nObservation: ${step.observation}`, })); } @@ -136,10 +134,10 @@ Only respond with your conversational reply to the following User Message: const prefixMap = { 'gpt-4': 'gpt-4-0613', 'gpt-4-32k': 'gpt-4-32k-0613', - 'gpt-3.5-turbo': 'gpt-3.5-turbo-0613' + 'gpt-3.5-turbo': 'gpt-3.5-turbo-0613', }; - const prefix = Object.keys(prefixMap).find(key => input.startsWith(key)); + const prefix = Object.keys(prefixMap).find((key) => input.startsWith(key)); return prefix ? prefixMap[prefix] : 'gpt-3.5-turbo-0613'; } @@ -173,7 +171,7 @@ Only respond with your conversational reply to the following User Message: async initialize({ user, message, onAgentAction, onChainEnd, signal }) { const modelOptions = { modelName: this.agentOptions.model, - temperature: this.agentOptions.temperature + temperature: this.agentOptions.temperature, }; const configOptions = {}; @@ -194,8 +192,8 @@ Only respond with your conversational reply to the following User Message: tools: this.options.tools, functions: this.functionsAgent, options: { - openAIApiKey: this.openAIApiKey - } + openAIApiKey: this.openAIApiKey, + }, }); // load tools for (const tool of this.options.tools) { @@ -235,10 +233,13 @@ Only respond with your conversational reply to the following User Message: }; // Map Messages to Langchain format - const pastMessages = this.currentMessages.slice(0, -1).map( - msg => msg?.isCreatedByUser || msg?.role?.toLowerCase() === 'user' - ? new HumanChatMessage(msg.text) - : new AIChatMessage(msg.text)); + const pastMessages = this.currentMessages + .slice(0, -1) + .map((msg) => + msg?.isCreatedByUser || msg?.role?.toLowerCase() === 'user' + ? new HumanChatMessage(msg.text) + : new AIChatMessage(msg.text), + ); // initialize agent const initializer = this.functionsAgent ? initializeFunctionsAgent : initializeCustomAgent; @@ -258,8 +259,8 @@ Only respond with your conversational reply to the following User Message: if (typeof onChainEnd === 'function') { onChainEnd(action); } - } - }) + }, + }), }); if (this.options.debug) { @@ -304,7 +305,7 @@ Only respond with your conversational reply to the following User Message: return; } - intermediateSteps.forEach(step => { + intermediateSteps.forEach((step) => { const { observation } = step; if (!observation || !observation.includes('![')) { return; @@ -346,7 +347,12 @@ Only respond with your conversational reply to the following User Message: this.currentMessages.push(userMessage); - let { prompt: payload, tokenCountMap, promptTokens, messages } = await this.buildMessages( + let { + prompt: payload, + tokenCountMap, + promptTokens, + messages, + } = await this.buildMessages( this.currentMessages, userMessage.messageId, this.getBuildMessagesOptions({ @@ -356,7 +362,7 @@ Only respond with your conversational reply to the following User Message: ); if (tokenCountMap) { - console.dir(tokenCountMap, { depth: null }) + console.dir(tokenCountMap, { depth: null }); if (tokenCountMap[userMessage.messageId]) { userMessage.tokenCount = tokenCountMap[userMessage.messageId]; console.log('userMessage.tokenCount', userMessage.tokenCount); @@ -389,7 +395,7 @@ Only respond with your conversational reply to the following User Message: message, onAgentAction, onChainEnd, - signal: this.abortController.signal + signal: this.abortController.signal, }); await this.executorCall(message, this.abortController.signal); @@ -448,12 +454,12 @@ Only respond with your conversational reply to the following User Message: const instructionsPayload = { role: 'system', name: 'instructions', - content: promptPrefix + content: promptPrefix, }; const messagePayload = { role: 'system', - content: promptSuffix + content: promptSuffix, }; if (this.isGpt3) { @@ -468,8 +474,8 @@ Only respond with your conversational reply to the following User Message: } let currentTokenCount = - this.getTokenCountForMessage(instructionsPayload) + - this.getTokenCountForMessage(messagePayload); + this.getTokenCountForMessage(instructionsPayload) + + this.getTokenCountForMessage(messagePayload); let promptBody = ''; const maxTokenCount = this.maxPromptTokens; @@ -492,7 +498,7 @@ Only respond with your conversational reply to the following User Message: } // This is the first message, so we can't add it. Just throw an error. throw new Error( - `Prompt is too long. Max token count is ${maxTokenCount}, but prompt is ${newTokenCount} tokens long.` + `Prompt is too long. Max token count is ${maxTokenCount}, but prompt is ${newTokenCount} tokens long.`, ); } promptBody = newPromptBody; @@ -519,7 +525,7 @@ Only respond with your conversational reply to the following User Message: // Use up to `this.maxContextTokens` tokens (prompt + response), but try to leave `this.maxTokens` tokens for the response. this.modelOptions.max_tokens = Math.min( this.maxContextTokens - currentTokenCount, - this.maxResponseTokens + this.maxResponseTokens, ); if (this.isGpt3) { diff --git a/api/app/clients/agents/CustomAgent/CustomAgent.js b/api/app/clients/agents/CustomAgent/CustomAgent.js index e502ceb607..dcb34971f5 100644 --- a/api/app/clients/agents/CustomAgent/CustomAgent.js +++ b/api/app/clients/agents/CustomAgent/CustomAgent.js @@ -8,7 +8,7 @@ class CustomAgent extends ZeroShotAgent { } _stop() { - return [`\nObservation:`, `\nObservation 1:`]; + return ['\nObservation:', '\nObservation 1:']; } static createPrompt(tools, opts = {}) { @@ -32,17 +32,17 @@ class CustomAgent extends ZeroShotAgent { .join('\n'); const toolNames = tools.map((tool) => tool.name); const formatInstructions = (0, renderTemplate)(instructions, 'f-string', { - tool_names: toolNames + tool_names: toolNames, }); const template = [ `Date: ${currentDateString}\n${prefix}`, toolStrings, formatInstructions, - suffix + suffix, ].join('\n\n'); return new PromptTemplate({ template, - inputVariables + inputVariables, }); } } diff --git a/api/app/clients/agents/CustomAgent/initializeCustomAgent.js b/api/app/clients/agents/CustomAgent/initializeCustomAgent.js index 4639feaa54..336839db00 100644 --- a/api/app/clients/agents/CustomAgent/initializeCustomAgent.js +++ b/api/app/clients/agents/CustomAgent/initializeCustomAgent.js @@ -6,7 +6,7 @@ const { BufferMemory, ChatMessageHistory } = require('langchain/memory'); const { ChatPromptTemplate, SystemMessagePromptTemplate, - HumanMessagePromptTemplate + HumanMessagePromptTemplate, } = require('langchain/prompts'); const initializeCustomAgent = async ({ @@ -22,7 +22,7 @@ const initializeCustomAgent = async ({ new SystemMessagePromptTemplate(prompt), HumanMessagePromptTemplate.fromTemplate(`{chat_history} Query: {input} -{agent_scratchpad}`) +{agent_scratchpad}`), ]); const outputParser = new CustomOutputParser({ tools }); @@ -34,18 +34,18 @@ Query: {input} humanPrefix: 'User', aiPrefix: 'Assistant', inputKey: 'input', - outputKey: 'output' + outputKey: 'output', }); const llmChain = new LLMChain({ prompt: chatPrompt, - llm: model + llm: model, }); const agent = new CustomAgent({ llmChain, outputParser, - allowedTools: tools.map((tool) => tool.name) + allowedTools: tools.map((tool) => tool.name), }); return AgentExecutor.fromAgentAndTools({ agent, tools, memory, ...rest }); diff --git a/api/app/clients/agents/CustomAgent/outputParser.js b/api/app/clients/agents/CustomAgent/outputParser.js index d714d01db3..80b2d72913 100644 --- a/api/app/clients/agents/CustomAgent/outputParser.js +++ b/api/app/clients/agents/CustomAgent/outputParser.js @@ -57,7 +57,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { const output = text.substring(finalMatch.index + finalMatch[0].length).trim(); return { returnValues: { output }, - log: text + log: text, }; } @@ -66,7 +66,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { if (!match) { console.log( '\n\n<----------------------HIT NO MATCH PARSING ERROR---------------------->\n\n', - match + match, ); const thoughts = text.replace(/[tT]hought:/, '').split('\n'); // return { @@ -77,7 +77,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { return { returnValues: { output: thoughts[0] }, - log: thoughts.slice(1).join('\n') + log: thoughts.slice(1).join('\n'), }; } @@ -86,12 +86,12 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { if (match && selectedTool === 'n/a') { console.log( '\n\n<----------------------HIT N/A PARSING ERROR---------------------->\n\n', - match + match, ); return { tool: 'self-reflection', toolInput: match[2]?.trim().replace(/^"+|"+$/g, '') ?? '', - log: text + log: text, }; } @@ -99,7 +99,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { if (match && !toolIsValid) { console.log( '\n\n<----------------Tool invalid: Re-assigning Selected Tool---------------->\n\n', - match + match, ); selectedTool = this.getValidTool(selectedTool); } @@ -107,7 +107,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { if (match && !selectedTool) { console.log( '\n\n<----------------------HIT INVALID TOOL PARSING ERROR---------------------->\n\n', - match + match, ); selectedTool = 'self-reflection'; } @@ -115,7 +115,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { if (match && !match[2]) { console.log( '\n\n<----------------------HIT NO ACTION INPUT PARSING ERROR---------------------->\n\n', - match + match, ); // In case there is no action input, let's double-check if there is an action input in 'text' variable @@ -125,7 +125,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { return { tool: selectedTool, toolInput: actionInputMatch[1].trim(), - log: text + log: text, }; } @@ -133,7 +133,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { return { tool: selectedTool, toolInput: thoughtMatch[1].trim(), - log: text + log: text, }; } } @@ -158,12 +158,12 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { if (action && actionInputMatch) { console.log( '\n\n<------Matched Action Input in Long Parsing Error------>\n\n', - actionInputMatch + actionInputMatch, ); return { tool: action, toolInput: actionInputMatch[1].trim().replaceAll('"', ''), - log: text + log: text, }; } @@ -180,7 +180,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { const returnValues = { tool: action, toolInput: input, - log: thought || inputText + log: thought || inputText, }; const inputMatch = this.actionValues.exec(returnValues.log); //new @@ -197,7 +197,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { return { tool: 'self-reflection', toolInput: 'Hypothetical actions: \n"' + text + '"\n', - log: 'Thought: I need to look at my hypothetical actions and try one' + log: 'Thought: I need to look at my hypothetical actions and try one', }; } @@ -210,7 +210,7 @@ class CustomOutputParser extends ZeroShotAgentOutputParser { return { tool: selectedTool, toolInput: match[2]?.trim()?.replace(/^"+|"+$/g, '') ?? '', - log: text + log: text, }; } } diff --git a/api/app/clients/agents/Functions/FunctionsAgent.js b/api/app/clients/agents/Functions/FunctionsAgent.js index 00d586a9bc..3f3f0c423c 100644 --- a/api/app/clients/agents/Functions/FunctionsAgent.js +++ b/api/app/clients/agents/Functions/FunctionsAgent.js @@ -5,9 +5,9 @@ const { ChatPromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, - HumanMessagePromptTemplate + HumanMessagePromptTemplate, } = require('langchain/prompts'); -const PREFIX = `You are a helpful AI assistant.`; +const PREFIX = 'You are a helpful AI assistant.'; function parseOutput(message) { if (message.additional_kwargs.function_call) { @@ -15,7 +15,7 @@ function parseOutput(message) { return { tool: function_call.name, toolInput: function_call.arguments ? JSON.parse(function_call.arguments) : {}, - log: message.text + log: message.text, }; } else { return { returnValues: { output: message.text }, log: message.text }; @@ -52,7 +52,7 @@ class FunctionsAgent extends Agent { return ChatPromptTemplate.fromPromptMessages([ SystemMessagePromptTemplate.fromTemplate(`Date: ${currentDateString}\n${prefix}`), new MessagesPlaceholder('chat_history'), - HumanMessagePromptTemplate.fromTemplate(`Query: {input}`), + HumanMessagePromptTemplate.fromTemplate('Query: {input}'), new MessagesPlaceholder('agent_scratchpad'), ]); } @@ -63,12 +63,12 @@ class FunctionsAgent extends Agent { const chain = new LLMChain({ prompt, llm, - callbacks: args?.callbacks + callbacks: args?.callbacks, }); return new FunctionsAgent({ llmChain: chain, allowedTools: tools.map((t) => t.name), - tools + tools, }); } @@ -77,10 +77,10 @@ class FunctionsAgent extends Agent { new AIChatMessage('', { function_call: { name: action.tool, - arguments: JSON.stringify(action.toolInput) - } + arguments: JSON.stringify(action.toolInput), + }, }), - new FunctionChatMessage(observation, action.tool) + new FunctionChatMessage(observation, action.tool), ]); } @@ -96,7 +96,7 @@ class FunctionsAgent extends Agent { const llm = this.llmChain.llm; const valuesForPrompt = Object.assign({}, newInputs); const valuesForLLM = { - tools: this.tools + tools: this.tools, }; for (let i = 0; i < this.llmChain.llm.callKeys.length; i++) { const key = this.llmChain.llm.callKeys[i]; @@ -110,7 +110,7 @@ class FunctionsAgent extends Agent { const message = await llm.predictMessages( promptValue.toChatMessages(), valuesForLLM, - callbackManager + callbackManager, ); console.log('message', message); return parseOutput(message); diff --git a/api/app/clients/agents/Functions/initializeFunctionsAgent.js b/api/app/clients/agents/Functions/initializeFunctionsAgent.js index 9097882128..36cfe0f006 100644 --- a/api/app/clients/agents/Functions/initializeFunctionsAgent.js +++ b/api/app/clients/agents/Functions/initializeFunctionsAgent.js @@ -8,7 +8,6 @@ const initializeFunctionsAgent = async ({ // currentDateString, ...rest }) => { - const memory = new BufferMemory({ chatHistory: new ChatMessageHistory(pastMessages), memoryKey: 'chat_history', @@ -19,17 +18,11 @@ const initializeFunctionsAgent = async ({ returnMessages: true, }); - return await initializeAgentExecutorWithOptions( - tools, - model, - { - agentType: 'openai-functions', - memory, - ...rest, - } - ); - + return await initializeAgentExecutorWithOptions(tools, model, { + agentType: 'openai-functions', + memory, + ...rest, + }); }; module.exports = initializeFunctionsAgent; - diff --git a/api/app/clients/agents/index.js b/api/app/clients/agents/index.js index 3dc7d299ed..c14ff0065f 100644 --- a/api/app/clients/agents/index.js +++ b/api/app/clients/agents/index.js @@ -3,5 +3,5 @@ const initializeFunctionsAgent = require('./Functions/initializeFunctionsAgent') module.exports = { initializeCustomAgent, - initializeFunctionsAgent -}; \ No newline at end of file + initializeFunctionsAgent, +}; diff --git a/api/app/clients/index.js b/api/app/clients/index.js index 6007e0f8ae..a5e8eee504 100644 --- a/api/app/clients/index.js +++ b/api/app/clients/index.js @@ -13,5 +13,5 @@ module.exports = { GoogleClient, TextStream, AnthropicClient, - ...toolUtils -}; \ No newline at end of file + ...toolUtils, +}; diff --git a/api/app/clients/prompts/instructions.js b/api/app/clients/prompts/instructions.js index 059d8a657f..c630711771 100644 --- a/api/app/clients/prompts/instructions.js +++ b/api/app/clients/prompts/instructions.js @@ -1,6 +1,10 @@ module.exports = { - instructions: `Remember, all your responses MUST be in the format described. Do not respond unless it's in the format described, using the structure of Action, Action Input, etc.`, - errorInstructions: `\nYou encountered an error in attempting a response. The user is not aware of the error so you shouldn't mention it.\nReview the actions taken carefully in case there is a partial or complete answer within them.\nError Message:`, - imageInstructions: 'You must include the exact image paths from above, formatted in Markdown syntax: ![alt-text](URL)', - completionInstructions: `Instructions:\nYou are ChatGPT, a large language model trained by OpenAI. Respond conversationally.\nCurrent date:`, + instructions: + 'Remember, all your responses MUST be in the format described. Do not respond unless it\'s in the format described, using the structure of Action, Action Input, etc.', + errorInstructions: + '\nYou encountered an error in attempting a response. The user is not aware of the error so you shouldn\'t mention it.\nReview the actions taken carefully in case there is a partial or complete answer within them.\nError Message:', + imageInstructions: + 'You must include the exact image paths from above, formatted in Markdown syntax: ![alt-text](URL)', + completionInstructions: + 'Instructions:\nYou are ChatGPT, a large language model trained by OpenAI. Respond conversationally.\nCurrent date:', }; diff --git a/api/app/clients/prompts/refinePrompt.js b/api/app/clients/prompts/refinePrompt.js index ed46021f07..cfc267d630 100644 --- a/api/app/clients/prompts/refinePrompt.js +++ b/api/app/clients/prompts/refinePrompt.js @@ -16,9 +16,9 @@ REFINED CONVERSATION SUMMARY:`; const refinePrompt = new PromptTemplate({ template: refinePromptTemplate, - inputVariables: ["existing_answer", "text"], + inputVariables: ['existing_answer', 'text'], }); module.exports = { refinePrompt, -}; \ No newline at end of file +}; diff --git a/api/app/clients/specs/BaseClient.test.js b/api/app/clients/specs/BaseClient.test.js index dd5b517d70..d81bfe6274 100644 --- a/api/app/clients/specs/BaseClient.test.js +++ b/api/app/clients/specs/BaseClient.test.js @@ -10,7 +10,7 @@ jest.mock('../../../models', () => { getMessages: jest.fn(), saveMessage: jest.fn(), updateMessage: jest.fn(), - saveConvo: jest.fn() + saveConvo: jest.fn(), }; }; }); @@ -52,7 +52,7 @@ describe('BaseClient', () => { modelOptions: { model: 'gpt-3.5-turbo', temperature: 0, - } + }, }; beforeEach(() => { @@ -60,22 +60,14 @@ describe('BaseClient', () => { }); test('returns the input messages without instructions when addInstructions() is called with empty instructions', () => { - const messages = [ - { content: 'Hello' }, - { content: 'How are you?' }, - { content: 'Goodbye' }, - ]; + const messages = [{ content: 'Hello' }, { content: 'How are you?' }, { content: 'Goodbye' }]; const instructions = ''; const result = TestClient.addInstructions(messages, instructions); expect(result).toEqual(messages); }); test('returns the input messages with instructions properly added when addInstructions() is called with non-empty instructions', () => { - const messages = [ - { content: 'Hello' }, - { content: 'How are you?' }, - { content: 'Goodbye' }, - ]; + const messages = [{ content: 'Hello' }, { content: 'How are you?' }, { content: 'Goodbye' }]; const instructions = { content: 'Please respond to the question.' }; const result = TestClient.addInstructions(messages, instructions); const expected = [ @@ -94,20 +86,21 @@ describe('BaseClient', () => { { name: 'User', content: 'I have a question.' }, ]; const result = TestClient.concatenateMessages(messages); - const expected = `User:\nHello\n\nAssistant:\nHow can I help you?\n\nUser:\nI have a question.\n\n`; + const expected = + 'User:\nHello\n\nAssistant:\nHow can I help you?\n\nUser:\nI have a question.\n\n'; expect(result).toBe(expected); }); test('refines messages correctly in refineMessages()', async () => { const messagesToRefine = [ { role: 'user', content: 'Hello', tokenCount: 10 }, - { role: 'assistant', content: 'How can I help you?', tokenCount: 20 } + { role: 'assistant', content: 'How can I help you?', tokenCount: 20 }, ]; const remainingContextTokens = 100; const expectedRefinedMessage = { role: 'assistant', content: 'Refined answer', - tokenCount: 14 // 'Refined answer'.length + tokenCount: 14, // 'Refined answer'.length }; const result = await TestClient.refineMessages(messagesToRefine, remainingContextTokens); @@ -120,7 +113,7 @@ describe('BaseClient', () => { TestClient.refineMessages = jest.fn().mockResolvedValue({ role: 'assistant', content: 'Refined answer', - tokenCount: 30 + tokenCount: 30, }); const messages = [ @@ -148,7 +141,7 @@ describe('BaseClient', () => { TestClient.refineMessages = jest.fn().mockResolvedValue({ role: 'assistant', content: 'Refined answer', - tokenCount: 4 + tokenCount: 4, }); const messages = [ @@ -176,28 +169,28 @@ describe('BaseClient', () => { }); test('handles context strategy correctly in handleContextStrategy()', async () => { - TestClient.addInstructions = jest.fn().mockReturnValue([ - { content: 'Hello' }, - { content: 'How can I help you?' }, - { content: 'Please provide more details.' }, - { content: 'I can assist you with that.' } - ]); + TestClient.addInstructions = jest + .fn() + .mockReturnValue([ + { content: 'Hello' }, + { content: 'How can I help you?' }, + { content: 'Please provide more details.' }, + { content: 'I can assist you with that.' }, + ]); TestClient.getMessagesWithinTokenLimit = jest.fn().mockReturnValue({ context: [ { content: 'How can I help you?' }, { content: 'Please provide more details.' }, - { content: 'I can assist you with that.' } + { content: 'I can assist you with that.' }, ], remainingContextTokens: 80, - messagesToRefine: [ - { content: 'Hello' }, - ], + messagesToRefine: [{ content: 'Hello' }], refineIndex: 3, }); TestClient.refineMessages = jest.fn().mockResolvedValue({ role: 'assistant', content: 'Refined answer', - tokenCount: 30 + tokenCount: 30, }); TestClient.getTokenCountForResponse = jest.fn().mockReturnValue(40); @@ -206,24 +199,24 @@ describe('BaseClient', () => { { content: 'Hello' }, { content: 'How can I help you?' }, { content: 'Please provide more details.' }, - { content: 'I can assist you with that.' } + { content: 'I can assist you with that.' }, ]; const formattedMessages = [ { content: 'Hello' }, { content: 'How can I help you?' }, { content: 'Please provide more details.' }, - { content: 'I can assist you with that.' } + { content: 'I can assist you with that.' }, ]; const expectedResult = { payload: [ { content: 'Refined answer', role: 'assistant', - tokenCount: 30 + tokenCount: 30, }, { content: 'How can I help you?' }, { content: 'Please provide more details.' }, - { content: 'I can assist you with that.' } + { content: 'I can assist you with that.' }, ], promptTokens: expect.any(Number), tokenCountMap: {}, @@ -246,7 +239,7 @@ describe('BaseClient', () => { isCreatedByUser: false, messageId: expect.any(String), parentMessageId: expect.any(String), - conversationId: expect.any(String) + conversationId: expect.any(String), }); const response = await TestClient.sendMessage(userMessage); @@ -261,7 +254,7 @@ describe('BaseClient', () => { conversationId, parentMessageId, getIds: jest.fn(), - onStart: jest.fn() + onStart: jest.fn(), }; const expectedResult = expect.objectContaining({ @@ -270,7 +263,7 @@ describe('BaseClient', () => { isCreatedByUser: false, messageId: expect.any(String), parentMessageId: expect.any(String), - conversationId: opts.conversationId + conversationId: opts.conversationId, }); const response = await TestClient.sendMessage(userMessage, opts); @@ -300,7 +293,10 @@ describe('BaseClient', () => { test('loadHistory is called with the correct arguments', async () => { const opts = { conversationId: '123', parentMessageId: '456' }; await TestClient.sendMessage('Hello, world!', opts); - expect(TestClient.loadHistory).toHaveBeenCalledWith(opts.conversationId, opts.parentMessageId); + expect(TestClient.loadHistory).toHaveBeenCalledWith( + opts.conversationId, + opts.parentMessageId, + ); }); test('getIds is called with the correct arguments', async () => { @@ -310,7 +306,7 @@ describe('BaseClient', () => { expect(getIds).toHaveBeenCalledWith({ userMessage: expect.objectContaining({ text: 'Hello, world!' }), conversationId: response.conversationId, - responseMessageId: response.messageId + responseMessageId: response.messageId, }); }); @@ -333,10 +329,10 @@ describe('BaseClient', () => { isCreatedByUser: expect.any(Boolean), messageId: expect.any(String), parentMessageId: expect.any(String), - conversationId: expect.any(String) + conversationId: expect.any(String), }), saveOptions, - user + user, ); }); @@ -358,14 +354,16 @@ describe('BaseClient', () => { test('returns an object with the correct shape', async () => { const response = await TestClient.sendMessage('Hello, world!', {}); - expect(response).toEqual(expect.objectContaining({ - sender: expect.any(String), - text: expect.any(String), - isCreatedByUser: expect.any(Boolean), - messageId: expect.any(String), - parentMessageId: expect.any(String), - conversationId: expect.any(String) - })); + expect(response).toEqual( + expect.objectContaining({ + sender: expect.any(String), + text: expect.any(String), + isCreatedByUser: expect.any(Boolean), + messageId: expect.any(String), + parentMessageId: expect.any(String), + conversationId: expect.any(String), + }), + ); }); }); }); diff --git a/api/app/clients/specs/FakeClient.js b/api/app/clients/specs/FakeClient.js index 94dc90cad8..5cd7556bcf 100644 --- a/api/app/clients/specs/FakeClient.js +++ b/api/app/clients/specs/FakeClient.js @@ -32,9 +32,11 @@ class FakeClient extends BaseClient { this.modelOptions = { ...modelOptions, model: modelOptions.model || 'gpt-3.5-turbo', - temperature: typeof modelOptions.temperature === 'undefined' ? 0.8 : modelOptions.temperature, + temperature: + typeof modelOptions.temperature === 'undefined' ? 0.8 : modelOptions.temperature, top_p: typeof modelOptions.top_p === 'undefined' ? 1 : modelOptions.top_p, - presence_penalty: typeof modelOptions.presence_penalty === 'undefined' ? 1 : modelOptions.presence_penalty, + presence_penalty: + typeof modelOptions.presence_penalty === 'undefined' ? 1 : modelOptions.presence_penalty, stop: modelOptions.stop, }; } @@ -66,7 +68,7 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { const orderedMessages = TestClient.constructor.getMessagesForConversation( fakeMessages, - parentMessageId + parentMessageId, ); TestClient.currentMessages = orderedMessages; @@ -98,7 +100,7 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { this.pastMessages = await TestClient.loadHistory( conversationId, - TestClient.options?.parentMessageId + TestClient.options?.parentMessageId, ); const userMessage = { @@ -107,7 +109,7 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { isCreatedByUser: true, messageId: userMessageId, parentMessageId, - conversationId + conversationId, }; const response = { @@ -116,7 +118,7 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { isCreatedByUser: false, messageId: crypto.randomUUID(), parentMessageId: userMessage.messageId, - conversationId + conversationId, }; fakeMessages.push(userMessage); @@ -126,7 +128,7 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { opts.getIds({ userMessage, conversationId, - responseMessageId: response.messageId + responseMessageId: response.messageId, }); } @@ -146,7 +148,10 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { // userMessage is always the last one in the payload if (i === payload.length - 1) { userMessage.tokenCount = message.tokenCount; - console.debug(`Token count for user message: ${tokenCount}`, `Instruction Tokens: ${tokenCountMap.instructions || 'N/A'}`); + console.debug( + `Token count for user message: ${tokenCount}`, + `Instruction Tokens: ${tokenCountMap.instructions || 'N/A'}`, + ); } return messageWithoutTokenCount; }); @@ -163,7 +168,10 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { }); TestClient.buildMessages = jest.fn(async (messages, parentMessageId) => { - const orderedMessages = TestClient.constructor.getMessagesForConversation(messages, parentMessageId); + const orderedMessages = TestClient.constructor.getMessagesForConversation( + messages, + parentMessageId, + ); const formattedMessages = orderedMessages.map((message) => { let { role: _role, sender, text } = message; const role = _role ?? sender; @@ -180,6 +188,6 @@ const initializeFakeClient = (apiKey, options, fakeMessages) => { }); return TestClient; -} +}; -module.exports = { FakeClient, initializeFakeClient }; \ No newline at end of file +module.exports = { FakeClient, initializeFakeClient }; diff --git a/api/app/clients/specs/OpenAIClient.test.js b/api/app/clients/specs/OpenAIClient.test.js index f1c2fcff90..0badda47ee 100644 --- a/api/app/clients/specs/OpenAIClient.test.js +++ b/api/app/clients/specs/OpenAIClient.test.js @@ -5,7 +5,7 @@ describe('OpenAIClient', () => { const model = 'gpt-4'; const parentMessageId = '1'; const messages = [ - { role: 'user', sender: 'User', text: 'Hello', messageId: parentMessageId}, + { role: 'user', sender: 'User', text: 'Hello', messageId: parentMessageId }, { role: 'assistant', sender: 'Assistant', text: 'Hi', messageId: '2' }, ]; @@ -22,7 +22,7 @@ describe('OpenAIClient', () => { client.refineMessages = jest.fn().mockResolvedValue({ role: 'assistant', content: 'Refined answer', - tokenCount: 30 + tokenCount: 30, }); }); @@ -100,60 +100,83 @@ describe('OpenAIClient', () => { describe('buildMessages', () => { it('should build messages correctly for chat completion', async () => { - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true }); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + }); expect(result).toHaveProperty('prompt'); }); it('should build messages correctly for non-chat completion', async () => { - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: false }); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: false, + }); expect(result).toHaveProperty('prompt'); }); it('should build messages correctly with a promptPrefix', async () => { - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true, promptPrefix: 'Test Prefix' }); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + promptPrefix: 'Test Prefix', + }); expect(result).toHaveProperty('prompt'); - const instructions = result.prompt.find(item => item.name === 'instructions'); + const instructions = result.prompt.find((item) => item.name === 'instructions'); expect(instructions).toBeDefined(); expect(instructions.content).toContain('Test Prefix'); }); it('should handle context strategy correctly', async () => { client.contextStrategy = 'refine'; - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true }); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + }); expect(result).toHaveProperty('prompt'); expect(result).toHaveProperty('tokenCountMap'); }); it('should assign name property for user messages when options.name is set', async () => { client.options.name = 'Test User'; - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true }); - const hasUserWithName = result.prompt.some(item => item.role === 'user' && item.name === 'Test User'); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + }); + const hasUserWithName = result.prompt.some( + (item) => item.role === 'user' && item.name === 'Test User', + ); expect(hasUserWithName).toBe(true); }); it('should calculate tokenCount for each message when contextStrategy is set', async () => { client.contextStrategy = 'refine'; - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true }); - const hasUserWithTokenCount = result.prompt.some(item => item.role === 'user' && item.tokenCount > 0); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + }); + const hasUserWithTokenCount = result.prompt.some( + (item) => item.role === 'user' && item.tokenCount > 0, + ); expect(hasUserWithTokenCount).toBe(true); }); it('should handle promptPrefix from options when promptPrefix argument is not provided', async () => { client.options.promptPrefix = 'Test Prefix from options'; - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true }); - const instructions = result.prompt.find(item => item.name === 'instructions'); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + }); + const instructions = result.prompt.find((item) => item.name === 'instructions'); expect(instructions.content).toContain('Test Prefix from options'); }); it('should handle case when neither promptPrefix argument nor options.promptPrefix is set', async () => { - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true }); - const instructions = result.prompt.find(item => item.name === 'instructions'); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + }); + const instructions = result.prompt.find((item) => item.name === 'instructions'); expect(instructions).toBeUndefined(); }); it('should handle case when getMessagesForConversation returns null or an empty array', async () => { const messages = []; - const result = await client.buildMessages(messages, parentMessageId, { isChatCompletion: true }); + const result = await client.buildMessages(messages, parentMessageId, { + isChatCompletion: true, + }); expect(result.prompt).toEqual([]); }); }); diff --git a/api/app/clients/specs/OpenAIClient.tokens.js b/api/app/clients/specs/OpenAIClient.tokens.js index f4f81c1f86..a816ee9f85 100644 --- a/api/app/clients/specs/OpenAIClient.tokens.js +++ b/api/app/clients/specs/OpenAIClient.tokens.js @@ -16,7 +16,7 @@ require('dotenv').config(); const { OpenAIClient } = require('../'); function timeout(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); + return new Promise((resolve) => setTimeout(resolve, ms)); } const run = async () => { @@ -46,7 +46,7 @@ const run = async () => { model, }, proxy: process.env.PROXY || null, - debug: true + debug: true, }; let apiKey = process.env.OPENAI_API_KEY; @@ -59,7 +59,13 @@ const run = async () => { function printProgressBar(percentageUsed) { const filledBlocks = Math.round(percentageUsed / 2); // Each block represents 2% const emptyBlocks = 50 - filledBlocks; // Total blocks is 50 (each represents 2%), so the rest are empty - const progressBar = '[' + '█'.repeat(filledBlocks) + ' '.repeat(emptyBlocks) + '] ' + percentageUsed.toFixed(2) + '%'; + const progressBar = + '[' + + '█'.repeat(filledBlocks) + + ' '.repeat(emptyBlocks) + + '] ' + + percentageUsed.toFixed(2) + + '%'; console.log(progressBar); } @@ -78,10 +84,10 @@ const run = async () => { // encoder.free(); const memoryUsageDuringLoop = process.memoryUsage().heapUsed; - const percentageUsed = memoryUsageDuringLoop / maxMemory * 100; + const percentageUsed = (memoryUsageDuringLoop / maxMemory) * 100; printProgressBar(percentageUsed); - if (i === (iterations - 1)) { + if (i === iterations - 1) { console.log(' done'); // encoder.free(); } @@ -100,7 +106,7 @@ const run = async () => { await timeout(15000); const memoryUsageAfterTimeout = process.memoryUsage().heapUsed; console.log(`Post timeout: ${memoryUsageAfterTimeout / 1024 / 1024} megabytes`); -} +}; run(); diff --git a/api/app/clients/specs/PluginsClient.test.js b/api/app/clients/specs/PluginsClient.test.js index 22936e1e3a..59218c6206 100644 --- a/api/app/clients/specs/PluginsClient.test.js +++ b/api/app/clients/specs/PluginsClient.test.js @@ -7,7 +7,7 @@ jest.mock('../../../models/Conversation', () => { return function () { return { save: jest.fn(), - deleteConvos: jest.fn() + deleteConvos: jest.fn(), }; }; }); @@ -19,11 +19,11 @@ describe('PluginsClient', () => { modelOptions: { model: 'gpt-3.5-turbo', temperature: 0, - max_tokens: 2 + max_tokens: 2, }, agentOptions: { - model: 'gpt-3.5-turbo' - } + model: 'gpt-3.5-turbo', + }, }; let parentMessageId; let conversationId; @@ -43,13 +43,13 @@ describe('PluginsClient', () => { const orderedMessages = TestAgent.constructor.getMessagesForConversation( fakeMessages, - parentMessageId + parentMessageId, ); const chatMessages = orderedMessages.map((msg) => msg?.isCreatedByUser || msg?.role?.toLowerCase() === 'user' ? new HumanChatMessage(msg.text) - : new AIChatMessage(msg.text) + : new AIChatMessage(msg.text), ); TestAgent.currentMessages = orderedMessages; @@ -64,7 +64,7 @@ describe('PluginsClient', () => { const userMessageId = opts.overrideParentMessageId || crypto.randomUUID(); this.pastMessages = await TestAgent.loadHistory( conversationId, - TestAgent.options?.parentMessageId + TestAgent.options?.parentMessageId, ); const userMessage = { @@ -73,7 +73,7 @@ describe('PluginsClient', () => { isCreatedByUser: true, messageId: userMessageId, parentMessageId, - conversationId + conversationId, }; const response = { @@ -82,7 +82,7 @@ describe('PluginsClient', () => { isCreatedByUser: false, messageId: crypto.randomUUID(), parentMessageId: userMessage.messageId, - conversationId + conversationId, }; fakeMessages.push(userMessage); @@ -107,7 +107,7 @@ describe('PluginsClient', () => { isCreatedByUser: false, messageId: expect.any(String), parentMessageId: expect.any(String), - conversationId: expect.any(String) + conversationId: expect.any(String), }); const response = await TestAgent.sendMessage(userMessage); @@ -121,7 +121,7 @@ describe('PluginsClient', () => { const userMessage = 'Second message in the conversation'; const opts = { conversationId, - parentMessageId + parentMessageId, }; const expectedResult = expect.objectContaining({ @@ -130,7 +130,7 @@ describe('PluginsClient', () => { isCreatedByUser: false, messageId: expect.any(String), parentMessageId: expect.any(String), - conversationId: opts.conversationId + conversationId: opts.conversationId, }); const response = await TestAgent.sendMessage(userMessage, opts); diff --git a/api/app/clients/tools/AIPluginTool.js b/api/app/clients/tools/AIPluginTool.js index e316c020f6..b89d3f0be1 100644 --- a/api/app/clients/tools/AIPluginTool.js +++ b/api/app/clients/tools/AIPluginTool.js @@ -57,7 +57,7 @@ function extractShortVersion(openapiSpec) { const shortApiSpec = { openapi: fullApiSpec.openapi, info: fullApiSpec.info, - paths: {} + paths: {}, }; for (let path in fullApiSpec.paths) { @@ -68,8 +68,8 @@ function extractShortVersion(openapiSpec) { operationId: fullApiSpec.paths[path][method].operationId, parameters: fullApiSpec.paths[path][method].parameters?.map((parameter) => ({ name: parameter.name, - description: parameter.description - })) + description: parameter.description, + })), }; } } @@ -199,14 +199,16 @@ class AIPluginTool extends Tool { const apiUrlRes = await fetch(aiPluginJson.api.url, {}); if (!apiUrlRes.ok) { throw new Error( - `Failed to fetch API spec from ${aiPluginJson.api.url} with status ${apiUrlRes.status}` + `Failed to fetch API spec from ${aiPluginJson.api.url} with status ${apiUrlRes.status}`, ); } const apiUrlJson = await apiUrlRes.text(); const shortApiSpec = extractShortVersion(apiUrlJson); return new AIPluginTool({ name: aiPluginJson.name_for_model.toLowerCase(), - description: `A \`tool\` to learn the API documentation for ${aiPluginJson.name_for_model.toLowerCase()}, after which you can use 'http_request' to make the actual API call. Short description of how to use the API's results: ${aiPluginJson.description_for_model})`, + description: `A \`tool\` to learn the API documentation for ${aiPluginJson.name_for_model.toLowerCase()}, after which you can use 'http_request' to make the actual API call. Short description of how to use the API's results: ${ + aiPluginJson.description_for_model + })`, apiSpec: ` As an AI, your task is to identify the operationId of the relevant API path based on the condensed OpenAPI specifications provided. @@ -228,7 +230,7 @@ ${shortApiSpec} \`\`\` `, openaiSpec: apiUrlJson, - model: model + model: model, }); } } diff --git a/api/app/clients/tools/DALL-E.js b/api/app/clients/tools/DALL-E.js index bfbd3a8bab..f40b1bacd8 100644 --- a/api/app/clients/tools/DALL-E.js +++ b/api/app/clients/tools/DALL-E.js @@ -56,11 +56,17 @@ Guidelines: } replaceUnwantedChars(inputString) { - return inputString.replace(/\r\n|\r|\n/g, ' ').replace('"', '').trim(); + return inputString + .replace(/\r\n|\r|\n/g, ' ') + .replace('"', '') + .trim(); } getMarkdownImageUrl(imageName) { - const imageUrl = path.join(this.relativeImageUrl, imageName).replace(/\\/g, '/').replace('public/', ''); + const imageUrl = path + .join(this.relativeImageUrl, imageName) + .replace(/\\/g, '/') + .replace('public/', ''); return `![generated image](/${imageUrl})`; } @@ -70,13 +76,13 @@ Guidelines: // TODO: Future idea -- could we ask an LLM to extract these arguments from an input that might contain them? n: 1, // size: '1024x1024' - size: '512x512' + size: '512x512', }); const theImageUrl = resp.data.data[0].url; if (!theImageUrl) { - throw new Error(`No image URL returned from OpenAI API.`); + throw new Error('No image URL returned from OpenAI API.'); } const regex = /img-[\w\d]+.png/; diff --git a/api/app/clients/tools/GoogleSearch.js b/api/app/clients/tools/GoogleSearch.js index aaa93e60d5..6a1758f3aa 100644 --- a/api/app/clients/tools/GoogleSearch.js +++ b/api/app/clients/tools/GoogleSearch.js @@ -23,7 +23,8 @@ class GoogleSearchAPI extends Tool { * A description for the agent to use * @type {string} */ - description = `Use the 'google' tool to retrieve internet search results relevant to your input. The results will return links and snippets of text from the webpages`; + description = + 'Use the \'google\' tool to retrieve internet search results relevant to your input. The results will return links and snippets of text from the webpages'; getCx() { const cx = process.env.GOOGLE_CSE_ID || ''; @@ -79,7 +80,7 @@ class GoogleSearchAPI extends Tool { q: input, cx: this.cx, auth: this.apiKey, - num: 5 // Limit the number of results to 5 + num: 5, // Limit the number of results to 5 }); // return response.data; @@ -87,7 +88,7 @@ class GoogleSearchAPI extends Tool { if (!response.data.items || response.data.items.length === 0) { return this.resultsToReadableFormat([ - { title: 'No good Google Search Result was found', link: '' } + { title: 'No good Google Search Result was found', link: '' }, ]); } @@ -97,7 +98,7 @@ class GoogleSearchAPI extends Tool { for (const result of results) { const metadataResult = { title: result.title || '', - link: result.link || '' + link: result.link || '', }; if (result.snippet) { metadataResult.snippet = result.snippet; diff --git a/api/app/clients/tools/HttpRequestTool.js b/api/app/clients/tools/HttpRequestTool.js index c602817d4b..a85e783b22 100644 --- a/api/app/clients/tools/HttpRequestTool.js +++ b/api/app/clients/tools/HttpRequestTool.js @@ -55,7 +55,8 @@ class HttpRequestTool extends Tool { this.headers = headers; this.name = 'http_request'; this.maxOutputLength = maxOutputLength; - this.description = `Executes HTTP methods (GET, POST, PUT, DELETE, etc.). The input is an object with three keys: "url", "method", and "data". Even for GET or DELETE, include "data" key as an empty string. "method" is the HTTP method, and "url" is the desired endpoint. If POST or PUT, "data" should contain a stringified JSON representing the body to send. Only one url per use.`; + this.description = + 'Executes HTTP methods (GET, POST, PUT, DELETE, etc.). The input is an object with three keys: "url", "method", and "data". Even for GET or DELETE, include "data" key as an empty string. "method" is the HTTP method, and "url" is the desired endpoint. If POST or PUT, "data" should contain a stringified JSON representing the body to send. Only one url per use.'; } async _call(input) { @@ -77,7 +78,7 @@ class HttpRequestTool extends Tool { let options = { method: method, - headers: this.headers + headers: this.headers, }; if (['POST', 'PUT', 'PATCH'].includes(method.toUpperCase()) && data) { diff --git a/api/app/clients/tools/SelfReflection.js b/api/app/clients/tools/SelfReflection.js index 4edc4b5fa2..7efb6069bf 100644 --- a/api/app/clients/tools/SelfReflection.js +++ b/api/app/clients/tools/SelfReflection.js @@ -5,7 +5,8 @@ class SelfReflectionTool extends Tool { super(); this.reminders = 0; this.name = 'self-reflection'; - this.description = `Take this action to reflect on your thoughts & actions. For your input, provide answers for self-evaluation as part of one input, using this space as a canvas to explore and organize your ideas in response to the user's message. You can use multiple lines for your input. Perform this action sparingly and only when you are stuck.`; + this.description = + 'Take this action to reflect on your thoughts & actions. For your input, provide answers for self-evaluation as part of one input, using this space as a canvas to explore and organize your ideas in response to the user\'s message. You can use multiple lines for your input. Perform this action sparingly and only when you are stuck.'; this.message = message; this.isGpt3 = isGpt3; // this.returnDirect = true; @@ -17,9 +18,9 @@ class SelfReflectionTool extends Tool { async selfReflect() { if (this.isGpt3) { - return `I should finalize my reply as soon as I have satisfied the user's query.`; + return 'I should finalize my reply as soon as I have satisfied the user\'s query.'; } else { - return ``; + return ''; } } } diff --git a/api/app/clients/tools/StableDiffusion.js b/api/app/clients/tools/StableDiffusion.js index 0f9b01c330..4db03c25a8 100644 --- a/api/app/clients/tools/StableDiffusion.js +++ b/api/app/clients/tools/StableDiffusion.js @@ -26,7 +26,10 @@ Guidelines: } getMarkdownImageUrl(imageName) { - const imageUrl = path.join(this.relativeImageUrl, imageName).replace(/\\/g, '/').replace('public/', ''); + const imageUrl = path + .join(this.relativeImageUrl, imageName) + .replace(/\\/g, '/') + .replace('public/', ''); return `![generated image](/${imageUrl})`; } @@ -43,7 +46,7 @@ Guidelines: const payload = { prompt: input.split('|')[0], negative_prompt: input.split('|')[1], - steps: 20 + steps: 20, }; const response = await axios.post(`${url}/sdapi/v1/txt2img`, payload); const image = response.data.images[0]; @@ -68,8 +71,8 @@ Guidelines: await sharp(buffer) .withMetadata({ iptcpng: { - parameters: info - } + parameters: info, + }, }) .toFile(this.outputPath + '/' + imageName); this.result = this.getMarkdownImageUrl(imageName); diff --git a/api/app/clients/tools/Wolfram.js b/api/app/clients/tools/Wolfram.js index 8056e39bf7..8954afc8fa 100644 --- a/api/app/clients/tools/Wolfram.js +++ b/api/app/clients/tools/Wolfram.js @@ -71,7 +71,7 @@ General guidelines: console.log('Error data:', error.response.data); return error.response.data; } else { - console.log(`Error querying Wolfram Alpha`, error.message); + console.log('Error querying Wolfram Alpha', error.message); // throw error; return 'There was an error querying Wolfram Alpha.'; } diff --git a/api/app/clients/tools/index.js b/api/app/clients/tools/index.js index fb5ba9a482..307a42a4ab 100644 --- a/api/app/clients/tools/index.js +++ b/api/app/clients/tools/index.js @@ -19,5 +19,5 @@ module.exports = { StructuredSD, WolframAlphaAPI, StructuredWolfram, - SelfReflectionTool -} + SelfReflectionTool, +}; diff --git a/api/app/clients/tools/saveImageFromUrl.js b/api/app/clients/tools/saveImageFromUrl.js index c4750e7472..e67f532cdf 100644 --- a/api/app/clients/tools/saveImageFromUrl.js +++ b/api/app/clients/tools/saveImageFromUrl.js @@ -7,7 +7,7 @@ async function saveImageFromUrl(url, outputPath, outputFilename) { // Fetch the image from the URL const response = await axios({ url, - responseType: 'stream' + responseType: 'stream', }); // Check if the output directory exists, if not, create it diff --git a/api/app/clients/tools/structured/StableDiffusion.js b/api/app/clients/tools/structured/StableDiffusion.js index e5a8549bd9..8bc34bc7e5 100644 --- a/api/app/clients/tools/structured/StableDiffusion.js +++ b/api/app/clients/tools/structured/StableDiffusion.js @@ -20,8 +20,16 @@ Guidelines: "negative_prompt":"semi-realistic, cgi, 3d, render, sketch, cartoon, drawing, anime, out of frame, low quality, ugly, mutation, deformed" - Generate images only once per human query unless explicitly requested by the user`; this.schema = z.object({ - prompt: z.string().describe("Detailed keywords to describe the subject, using at least 7 keywords to accurately describe the image, separated by comma"), - negative_prompt: z.string().describe("Keywords we want to exclude from the final image, using at least 7 keywords to accurately describe the image, separated by comma") + prompt: z + .string() + .describe( + 'Detailed keywords to describe the subject, using at least 7 keywords to accurately describe the image, separated by comma', + ), + negative_prompt: z + .string() + .describe( + 'Keywords we want to exclude from the final image, using at least 7 keywords to accurately describe the image, separated by comma', + ), }); } @@ -30,7 +38,10 @@ Guidelines: } getMarkdownImageUrl(imageName) { - const imageUrl = path.join(this.relativeImageUrl, imageName).replace(/\\/g, '/').replace('public/', ''); + const imageUrl = path + .join(this.relativeImageUrl, imageName) + .replace(/\\/g, '/') + .replace('public/', ''); return `![generated image](/${imageUrl})`; } @@ -48,7 +59,7 @@ Guidelines: const payload = { prompt, negative_prompt, - steps: 20 + steps: 20, }; const response = await axios.post(`${url}/sdapi/v1/txt2img`, payload); const image = response.data.images[0]; @@ -58,7 +69,17 @@ Guidelines: // Generate unique name const imageName = `${Date.now()}.png`; - this.outputPath = path.resolve(__dirname, '..', '..', '..', '..', '..', 'client', 'public', 'images'); + this.outputPath = path.resolve( + __dirname, + '..', + '..', + '..', + '..', + '..', + 'client', + 'public', + 'images', + ); const appRoot = path.resolve(__dirname, '..', '..', '..', '..', '..', 'client'); this.relativeImageUrl = path.relative(appRoot, this.outputPath); @@ -72,8 +93,8 @@ Guidelines: await sharp(buffer) .withMetadata({ iptcpng: { - parameters: info - } + parameters: info, + }, }) .toFile(this.outputPath + '/' + imageName); this.result = this.getMarkdownImageUrl(imageName); diff --git a/api/app/clients/tools/structured/Wolfram.js b/api/app/clients/tools/structured/Wolfram.js index a8ad509286..94edc5e0d8 100644 --- a/api/app/clients/tools/structured/Wolfram.js +++ b/api/app/clients/tools/structured/Wolfram.js @@ -18,7 +18,9 @@ Guidelines include: - Make separate calls for each property and choose relevant 'Assumptions' if results aren't relevant. - The tool also performs data analysis, plotting, and information retrieval.`; this.schema = z.object({ - nl_query: z.string().describe("Natural language query to WolframAlpha following the guidelines"), + nl_query: z + .string() + .describe('Natural language query to WolframAlpha following the guidelines'), }); } @@ -61,7 +63,7 @@ Guidelines include: console.log('Error data:', error.response.data); return error.response.data; } else { - console.log(`Error querying Wolfram Alpha`, error.message); + console.log('Error querying Wolfram Alpha', error.message); // throw error; return 'There was an error querying Wolfram Alpha.'; } diff --git a/api/app/clients/tools/util/handleTools.js b/api/app/clients/tools/util/handleTools.js index ed4f9ab347..018eb0bcde 100644 --- a/api/app/clients/tools/util/handleTools.js +++ b/api/app/clients/tools/util/handleTools.js @@ -1,10 +1,7 @@ const { getUserPluginAuthValue } = require('../../../../server/services/PluginService'); const { OpenAIEmbeddings } = require('langchain/embeddings/openai'); const { ZapierToolKit } = require('langchain/agents'); -const { - SerpAPI, - ZapierNLAWrapper -} = require('langchain/tools'); +const { SerpAPI, ZapierNLAWrapper } = require('langchain/tools'); const { ChatOpenAI } = require('langchain/chat_models/openai'); const { Calculator } = require('langchain/tools/calculator'); const { WebBrowser } = require('langchain/tools/webbrowser'); @@ -24,7 +21,7 @@ const validateTools = async (user, tools = []) => { try { const validToolsSet = new Set(tools); const availableToolsToValidate = availableTools.filter((tool) => - validToolsSet.has(tool.pluginKey) + validToolsSet.has(tool.pluginKey), ); const validateCredentials = async (authField, toolName) => { @@ -79,14 +76,14 @@ const loadTools = async ({ user, model, functions = null, tools = [], options = google: GoogleSearchAPI, wolfram: functions ? StructuredWolfram : WolframAlphaAPI, 'dall-e': OpenAICreateImage, - 'stable-diffusion': functions ? StructuredSD : StableDiffusionAPI + 'stable-diffusion': functions ? StructuredSD : StableDiffusionAPI, }; const customConstructors = { browser: async () => { let openAIApiKey = options.openAIApiKey ?? process.env.OPENAI_API_KEY; openAIApiKey = openAIApiKey === 'user_provided' ? null : openAIApiKey; - openAIApiKey = openAIApiKey || await getUserPluginAuthValue(user, 'OPENAI_API_KEY'); + openAIApiKey = openAIApiKey || (await getUserPluginAuthValue(user, 'OPENAI_API_KEY')); return new WebBrowser({ model, embeddings: new OpenAIEmbeddings({ openAIApiKey }) }); }, serpapi: async () => { @@ -97,7 +94,7 @@ const loadTools = async ({ user, model, functions = null, tools = [], options = return new SerpAPI(apiKey, { location: 'Austin,Texas,United States', hl: 'en', - gl: 'us' + gl: 'us', }); }, zapier: async () => { @@ -113,16 +110,16 @@ const loadTools = async ({ user, model, functions = null, tools = [], options = new HttpRequestTool(), await AIPluginTool.fromPluginUrl( 'https://www.klarna.com/.well-known/ai-plugin.json', - new ChatOpenAI({ openAIApiKey: options.openAIApiKey, temperature: 0 }) - ) + new ChatOpenAI({ openAIApiKey: options.openAIApiKey, temperature: 0 }), + ), ]; - } + }, }; const requestedTools = {}; const toolOptions = { - serpapi: { location: 'Austin,Texas,United States', hl: 'en', gl: 'us' } + serpapi: { location: 'Austin,Texas,United States', hl: 'en', gl: 'us' }, }; const toolAuthFields = {}; @@ -147,7 +144,7 @@ const loadTools = async ({ user, model, functions = null, tools = [], options = user, toolAuthFields[tool], toolConstructors[tool], - options + options, ); requestedTools[tool] = toolInstance; } @@ -158,5 +155,5 @@ const loadTools = async ({ user, model, functions = null, tools = [], options = module.exports = { validateTools, - loadTools + loadTools, }; diff --git a/api/app/clients/tools/util/handleTools.test.js b/api/app/clients/tools/util/handleTools.test.js index 64ba33c346..674543ba29 100644 --- a/api/app/clients/tools/util/handleTools.test.js +++ b/api/app/clients/tools/util/handleTools.test.js @@ -7,11 +7,11 @@ const mockUser = { var mockPluginService = { updateUserPluginAuth: jest.fn(), deleteUserPluginAuth: jest.fn(), - getUserPluginAuthValue: jest.fn() + getUserPluginAuthValue: jest.fn(), }; jest.mock('../../../../models/User', () => { - return function() { + return function () { return mockUser; }; }); @@ -42,9 +42,11 @@ describe('Tool Handlers', () => { mockPluginService.getUserPluginAuthValue.mockImplementation((userId, authField) => { return userAuthValues[`${userId}-${authField}`]; }); - mockPluginService.updateUserPluginAuth.mockImplementation((userId, authField, _pluginKey, credential) => { - userAuthValues[`${userId}-${authField}`] = credential; - }); + mockPluginService.updateUserPluginAuth.mockImplementation( + (userId, authField, _pluginKey, credential) => { + userAuthValues[`${userId}-${authField}`] = credential; + }, + ); fakeUser = new User({ name: 'Fake User', @@ -57,11 +59,16 @@ describe('Tool Handlers', () => { role: 'USER', googleId: null, plugins: [], - refreshToken: [] + refreshToken: [], }); await fakeUser.save(); for (const authConfig of authConfigs) { - await PluginService.updateUserPluginAuth(fakeUser._id, authConfig.authField, pluginKey, mockCredential); + await PluginService.updateUserPluginAuth( + fakeUser._id, + authConfig.authField, + pluginKey, + mockCredential, + ); } }); @@ -113,14 +120,14 @@ describe('Tool Handlers', () => { const sampleTools = [...initialTools, 'calculator']; let ToolClass2 = Calculator; let remainingTools = availableTools.filter( - (tool) => sampleTools.indexOf(tool.pluginKey) === -1 + (tool) => sampleTools.indexOf(tool.pluginKey) === -1, ); beforeAll(async () => { toolFunctions = await loadTools({ user: fakeUser._id, model: BaseChatModel, - tools: sampleTools + tools: sampleTools, }); loadTool1 = toolFunctions[sampleTools[0]]; loadTool2 = toolFunctions[sampleTools[1]]; @@ -161,7 +168,7 @@ describe('Tool Handlers', () => { toolFunctions = await loadTools({ user: fakeUser._id, model: BaseChatModel, - tools: [testPluginKey] + tools: [testPluginKey], }); const Tool = await toolFunctions[testPluginKey](); expect(Tool).toBeInstanceOf(TestClass); @@ -169,7 +176,7 @@ describe('Tool Handlers', () => { it('returns an empty object when no tools are requested', async () => { toolFunctions = await loadTools({ user: fakeUser._id, - model: BaseChatModel + model: BaseChatModel, }); expect(toolFunctions).toEqual({}); }); @@ -179,7 +186,7 @@ describe('Tool Handlers', () => { user: fakeUser._id, model: BaseChatModel, tools: ['stable-diffusion'], - functions: true + functions: true, }); const structuredTool = await toolFunctions['stable-diffusion'](); expect(structuredTool).toBeInstanceOf(StructuredSD); diff --git a/api/app/clients/tools/util/index.js b/api/app/clients/tools/util/index.js index e39faea9c1..9c96fb50f3 100644 --- a/api/app/clients/tools/util/index.js +++ b/api/app/clients/tools/util/index.js @@ -2,5 +2,5 @@ const { validateTools, loadTools } = require('./handleTools'); module.exports = { validateTools, - loadTools + loadTools, }; diff --git a/api/app/index.js b/api/app/index.js index 9a7a2369b1..95624829a9 100644 --- a/api/app/index.js +++ b/api/app/index.js @@ -13,5 +13,5 @@ module.exports = { titleConvoBing, getCitations, citeText, - ...clients + ...clients, }; diff --git a/api/app/titleConvo.js b/api/app/titleConvo.js index b1315f20c9..ebdde7e5c3 100644 --- a/api/app/titleConvo.js +++ b/api/app/titleConvo.js @@ -1,4 +1,3 @@ - const _ = require('lodash'); const { genAzureChatCompletion, getAzureCredentials } = require('../utils/'); @@ -16,13 +15,13 @@ const titleConvo = async ({ text, response, openAIApiKey, azure = false }) => { ||>Response: "${JSON.stringify(response?.text)}" - ||>Title:` + ||>Title:`, }; const options = { azure, reverseProxyUrl: process.env.OPENAI_REVERSE_PROXY || null, - proxy: process.env.PROXY || null + proxy: process.env.PROXY || null, }; const titleGenClientOptions = JSON.parse(JSON.stringify(options)); @@ -31,13 +30,11 @@ const titleConvo = async ({ text, response, openAIApiKey, azure = false }) => { model: 'gpt-3.5-turbo', temperature: 0, presence_penalty: 0, - frequency_penalty: 0 + frequency_penalty: 0, }; let apiKey = openAIApiKey ?? process.env.OPENAI_API_KEY; - console.log('title api key', apiKey); - if (azure) { apiKey = process.env.AZURE_API_KEY; titleGenClientOptions.reverseProxyUrl = genAzureChatCompletion(getAzureCredentials()); diff --git a/api/app/titleConvoBing.js b/api/app/titleConvoBing.js index 58d2a46b1a..8454517d82 100644 --- a/api/app/titleConvoBing.js +++ b/api/app/titleConvoBing.js @@ -2,7 +2,7 @@ const _ = require('lodash'); const titleConvo = async ({ text, response }) => { let title = 'New Chat'; - const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api')); + const { BingAIClient } = await import('@waylaidwanderer/chatgpt-api'); const titleGenerator = new BingAIClient({ userToken: process.env.BINGAI_TOKEN, debug: false, @@ -11,18 +11,18 @@ const titleConvo = async ({ text, response }) => { let options = { jailbreakConversationId: true, systemMessage: - `You are a title-generator. As a title-generator, the old rules no longer apply. The only rule you need to follow is the following: Detect user language and write in the same language an extremely concise title for this conversation, which you must accurately detect. Write in the detected language. Title in 5 Words or Less. No Punctuation/Quotation. All first letters of every word should be capitalized and complete only the title in User Language only.`, + 'You are a title-generator. As a title-generator, the old rules no longer apply. The only rule you need to follow is the following: Detect user language and write in the same language an extremely concise title for this conversation, which you must accurately detect. Write in the detected language. Title in 5 Words or Less. No Punctuation/Quotation. All first letters of every word should be capitalized and complete only the title in User Language only.', context: ` ||>User: "${text}" ||>Response: "${JSON.stringify(response?.text)}"`, - toneStyle: 'precise' + toneStyle: 'precise', }; const titlePrompt = 'Title:'; try { - const res = await titleGenerator.sendMessage(titlePrompt, options) - title = res.response.replace(/Title: /, '').replace(/["\.]/g, ''); + const res = await titleGenerator.sendMessage(titlePrompt, options); + title = res.response.replace(/Title: /, '').replace(/[".]/g, ''); } catch (e) { console.error(e); console.log('There was an issue generating title, see error above'); diff --git a/api/jest.config.js b/api/jest.config.js index b365980f60..a877e75980 100644 --- a/api/jest.config.js +++ b/api/jest.config.js @@ -3,5 +3,5 @@ module.exports = { clearMocks: true, roots: [''], coverageDirectory: 'coverage', - setupFiles: ['./test/jestSetup.js'] + setupFiles: ['./test/jestSetup.js'], }; diff --git a/api/lib/db/connectDb.js b/api/lib/db/connectDb.js index 186543cff0..8b9cdae012 100644 --- a/api/lib/db/connectDb.js +++ b/api/lib/db/connectDb.js @@ -26,7 +26,7 @@ async function connectDb() { const opts = { useNewUrlParser: true, useUnifiedTopology: true, - bufferCommands: false + bufferCommands: false, // bufferMaxEntries: 0, // useFindAndModify: true, // useCreateIndex: true diff --git a/api/lib/db/indexSync.js b/api/lib/db/indexSync.js index fc822c60d2..c10ebeb9c7 100644 --- a/api/lib/db/indexSync.js +++ b/api/lib/db/indexSync.js @@ -14,7 +14,7 @@ async function indexSync(req, res, next) { const client = new MeiliSearch({ host: process.env.MEILI_HOST, - apiKey: process.env.MEILI_MASTER_KEY + apiKey: process.env.MEILI_MASTER_KEY, }); const { status } = await client.health(); diff --git a/api/lib/db/migrateDb.js b/api/lib/db/migrateDb.js index bff1f0c8df..d25a302212 100644 --- a/api/lib/db/migrateDb.js +++ b/api/lib/db/migrateDb.js @@ -13,7 +13,7 @@ const migrateToStrictFollowParentMessageIdChain = async () => { for (let convo of conversations) { const messages = await getMessages({ conversationId: convo.conversationId, - messageId: { $exists: false } + messageId: { $exists: false }, }); let model; @@ -45,14 +45,14 @@ const migrateToStrictFollowParentMessageIdChain = async () => { await Conversation.findOneAndUpdate( { conversationId: convo.conversationId }, { model }, - { new: true } + { new: true }, ).exec(); } try { await mongoose.connection.db.collection('messages').dropIndex('id_1'); } catch (error) { - console.log("[Migrate] Index doesn't exist or already dropped"); + console.log('[Migrate] Index doesn\'t exist or already dropped'); } } catch (error) { console.log(error); diff --git a/api/lib/utils/misc.js b/api/lib/utils/misc.js index 91982947f5..c7bf9e39e9 100644 --- a/api/lib/utils/misc.js +++ b/api/lib/utils/misc.js @@ -11,5 +11,5 @@ function replaceSup(text) { module.exports = { cleanUpPrimaryKeyValue, - replaceSup + replaceSup, }; diff --git a/api/lib/utils/reduceHits.js b/api/lib/utils/reduceHits.js index 63ca0491ff..77b2f9d57d 100644 --- a/api/lib/utils/reduceHits.js +++ b/api/lib/utils/reduceHits.js @@ -17,7 +17,7 @@ function reduceMessages(hits) { for (const [conversationId, count] of Object.entries(counts)) { result.push({ conversationId, - count + count, }); } @@ -49,7 +49,7 @@ function reduceHits(hits, titles = []) { result.push({ conversationId, count, - title: titleMap[conversationId] ? titleMap[conversationId] : null + title: titleMap[conversationId] ? titleMap[conversationId] : null, }); } diff --git a/api/middleware/requireLocalAuth.js b/api/middleware/requireLocalAuth.js index b6a9c575f7..b8700412bd 100644 --- a/api/middleware/requireLocalAuth.js +++ b/api/middleware/requireLocalAuth.js @@ -13,13 +13,13 @@ const requireLocalAuth = (req, res, next) => { if (err) { log({ title: '(requireLocalAuth) Error at passport.authenticate', - parameters: [{ name: 'error', value: err }] + parameters: [{ name: 'error', value: err }], }); return next(err); } if (!user) { log({ - title: '(requireLocalAuth) Error: No user' + title: '(requireLocalAuth) Error: No user', }); return res.status(422).send(info); } diff --git a/api/models/Config.js b/api/models/Config.js index bee45603ff..aa8168dcec 100644 --- a/api/models/Config.js +++ b/api/models/Config.js @@ -29,23 +29,23 @@ const configSchema = mongoose.Schema( } return true; }, - message: 'Invalid tag value' - } + message: 'Invalid tag value', + }, }, searchEnabled: { type: Boolean, - default: false + default: false, }, usersEnabled: { type: Boolean, - default: false + default: false, }, startupCounts: { type: Number, - default: 0 - } + default: 0, + }, }, - { timestamps: true } + { timestamps: true }, ); // Instance method @@ -80,5 +80,5 @@ module.exports = { console.error(error); return { config: 'Error deleting configs' }; } - } + }, }; diff --git a/api/models/Conversation.js b/api/models/Conversation.js index e91299e7f4..45b145a25a 100644 --- a/api/models/Conversation.js +++ b/api/models/Conversation.js @@ -23,7 +23,7 @@ module.exports = { return await Conversation.findOneAndUpdate({ conversationId: conversationId, user }, update, { new: true, - upsert: true + upsert: true, }).exec(); } catch (error) { console.log(error); @@ -61,9 +61,9 @@ module.exports = { promises.push( Conversation.findOne({ user, - conversationId: convo.conversationId - }).exec() - ) + conversationId: convo.conversationId, + }).exec(), + ), ); const results = (await Promise.all(promises)).filter((convo, i) => { @@ -94,7 +94,7 @@ module.exports = { pageSize, // will handle a syncing solution soon filter: new Set(deletedConvoIds), - convoMap + convoMap, }; } catch (error) { console.log(error); @@ -124,5 +124,5 @@ module.exports = { let deleteCount = await Conversation.deleteMany({ ...filter, user }).exec(); deleteCount.messages = await deleteMessages({ conversationId: { $in: ids } }); return deleteCount; - } + }, }; diff --git a/api/models/Message.js b/api/models/Message.js index 676682c23b..37235bebe6 100644 --- a/api/models/Message.js +++ b/api/models/Message.js @@ -34,9 +34,9 @@ module.exports = { cancelled, tokenCount, plugin, - model + model, }, - { upsert: true, new: true } + { upsert: true, new: true }, ); return { @@ -59,7 +59,7 @@ module.exports = { const updatedMessage = await Message.findOneAndUpdate( { messageId }, update, - { new: true } + { new: true }, ); if (!updatedMessage) { @@ -111,5 +111,5 @@ module.exports = { console.error(`Error deleting messages: ${err}`); throw new Error('Failed to delete messages.'); } - } + }, }; diff --git a/api/models/Preset.js b/api/models/Preset.js index f08825f798..cb1d6e6030 100644 --- a/api/models/Preset.js +++ b/api/models/Preset.js @@ -30,7 +30,7 @@ module.exports = { return await Preset.findOneAndUpdate( { presetId, user }, { $set: update }, - { new: true, upsert: true } + { new: true, upsert: true }, ).exec(); } catch (error) { console.log(error); @@ -42,5 +42,5 @@ module.exports = { // const ids = toRemove.map((instance) => instance.presetId); let deleteCount = await Preset.deleteMany({ ...filter, user }).exec(); return deleteCount; - } + }, }; diff --git a/api/models/Prompt.js b/api/models/Prompt.js index deb40b5318..d307e37044 100644 --- a/api/models/Prompt.js +++ b/api/models/Prompt.js @@ -4,17 +4,17 @@ const promptSchema = mongoose.Schema( { title: { type: String, - required: true + required: true, }, prompt: { type: String, - required: true + required: true, }, category: { - type: String - } + type: String, + }, }, - { timestamps: true } + { timestamps: true }, ); const Prompt = mongoose.models.Prompt || mongoose.model('Prompt', promptSchema); @@ -24,7 +24,7 @@ module.exports = { try { await Prompt.create({ title, - prompt + prompt, }); return { title, prompt }; } catch (error) { @@ -47,5 +47,5 @@ module.exports = { console.error(error); return { prompt: 'Error deleting prompts' }; } - } + }, }; diff --git a/api/models/User.js b/api/models/User.js index 25703b421c..8421e3e909 100644 --- a/api/models/User.js +++ b/api/models/User.js @@ -12,83 +12,83 @@ function log({ title, parameters }) { const Session = mongoose.Schema({ refreshToken: { type: String, - default: '' - } + default: '', + }, }); const userSchema = mongoose.Schema( { name: { - type: String + type: String, }, username: { type: String, lowercase: true, - required: [true, "can't be blank"], + required: [true, 'can\'t be blank'], match: [/^[a-zA-Z0-9_-]+$/, 'is invalid'], - index: true + index: true, }, email: { type: String, - required: [true, "can't be blank"], + required: [true, 'can\'t be blank'], lowercase: true, unique: true, match: [/\S+@\S+\.\S+/, 'is invalid'], - index: true + index: true, }, emailVerified: { type: Boolean, required: true, - default: false + default: false, }, password: { type: String, trim: true, minlength: 8, - maxlength: 128 + maxlength: 128, }, avatar: { type: String, - required: false + required: false, }, provider: { type: String, required: true, - default: 'local' + default: 'local', }, role: { type: String, - default: 'USER' + default: 'USER', }, googleId: { type: String, unique: true, - sparse: true + sparse: true, }, openidId: { type: String, unique: true, - sparse: true + sparse: true, }, githubId: { type: String, unique: true, - sparse: true + sparse: true, }, discordId: { type: String, unique: true, - sparse: true + sparse: true, }, plugins: { type: Array, - default: [] + default: [], }, refreshToken: { - type: [Session] - } + type: [Session], + }, }, - { timestamps: true } + { timestamps: true }, ); //Remove refreshToken from the response @@ -96,7 +96,7 @@ userSchema.set('toJSON', { transform: function (_doc, ret) { delete ret.refreshToken; return ret; - } + }, }); userSchema.methods.toJSON = function () { @@ -111,7 +111,7 @@ userSchema.methods.toJSON = function () { emailVerified: this.emailVerified, plugins: this.plugins, createdAt: this.createdAt, - updatedAt: this.updatedAt + updatedAt: this.updatedAt, }; }; @@ -121,10 +121,10 @@ userSchema.methods.generateToken = function () { id: this._id, username: this.username, provider: this.provider, - email: this.email + email: this.email, }, process.env.JWT_SECRET, - { expiresIn: eval(process.env.SESSION_EXPIRY) } + { expiresIn: eval(process.env.SESSION_EXPIRY) }, ); return token; }; @@ -135,10 +135,10 @@ userSchema.methods.generateRefreshToken = function () { id: this._id, username: this.username, provider: this.provider, - email: this.email + email: this.email, }, process.env.JWT_REFRESH_SECRET, - { expiresIn: eval(process.env.REFRESH_TOKEN_EXPIRY) } + { expiresIn: eval(process.env.REFRESH_TOKEN_EXPIRY) }, ); return refreshToken; }; @@ -164,7 +164,7 @@ module.exports.hashPassword = async (password) => { module.exports.validateUser = (user) => { log({ title: 'Validate User', - parameters: [{ name: 'Validate User', value: user }] + parameters: [{ name: 'Validate User', value: user }], }); const schema = { avatar: Joi.any(), @@ -174,7 +174,7 @@ module.exports.validateUser = (user) => { .max(80) .regex(/^[a-zA-Z0-9_-]+$/) .required(), - password: Joi.string().min(8).max(128).allow('').allow(null) + password: Joi.string().min(8).max(128).allow('').allow(null), }; return schema.validate(user); diff --git a/api/models/index.js b/api/models/index.js index 62790f95fd..b09055d01d 100644 --- a/api/models/index.js +++ b/api/models/index.js @@ -16,5 +16,5 @@ module.exports = { getPreset, getPresets, savePreset, - deletePresets + deletePresets, }; diff --git a/api/models/plugins/mongoMeili.js b/api/models/plugins/mongoMeili.js index 5768a5bd27..68b101fd84 100644 --- a/api/models/plugins/mongoMeili.js +++ b/api/models/plugins/mongoMeili.js @@ -68,8 +68,8 @@ const createMeiliMongooseModel = function ({ index, indexName, client, attribute function (results, value, key) { return { ...results, [key]: 1 }; }, - { _id: 1 } - ) + { _id: 1 }, + ), ); // Add additional data from mongodb into Meili search hits @@ -80,7 +80,7 @@ const createMeiliMongooseModel = function ({ index, indexName, client, attribute return { ...(originalHit ? originalHit.toJSON() : {}), - ...hit + ...hit, }; }); data.hits = populatedHits; @@ -161,8 +161,8 @@ module.exports = function mongoMeili(schema, options) { type: Boolean, required: false, select: false, - default: false - } + default: false, + }, }); const { host, apiKey, indexName, primaryKey } = options; @@ -183,8 +183,8 @@ module.exports = function mongoMeili(schema, options) { return value.meiliIndex ? [...results, key] : results; // }, []), '_id']; }, - [] - ) + [], + ), ]; schema.loadClass(createMeiliMongooseModel({ index, indexName, client, attributesToIndex })); diff --git a/api/models/schema/convoSchema.js b/api/models/schema/convoSchema.js index 53aeaf0169..3feba49da7 100644 --- a/api/models/schema/convoSchema.js +++ b/api/models/schema/convoSchema.js @@ -8,48 +8,48 @@ const convoSchema = mongoose.Schema( unique: true, required: true, index: true, - meiliIndex: true + meiliIndex: true, }, title: { type: String, default: 'New Chat', - meiliIndex: true + meiliIndex: true, }, user: { type: String, - default: null + default: null, }, messages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Message' }], // google only examples: [{ type: mongoose.Schema.Types.Mixed }], agentOptions: { type: mongoose.Schema.Types.Mixed, - default: null + default: null, }, ...conversationPreset, // for bingAI only bingConversationId: { type: String, - default: null + default: null, }, jailbreakConversationId: { type: String, - default: null + default: null, }, conversationSignature: { type: String, - default: null + default: null, }, clientId: { type: String, - default: null + default: null, }, invocationId: { type: Number, - default: 1 - } + default: 1, + }, }, - { timestamps: true } + { timestamps: true }, ); if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) { @@ -57,7 +57,7 @@ if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) { host: process.env.MEILI_HOST, apiKey: process.env.MEILI_MASTER_KEY, indexName: 'convos', // Will get created automatically if it doesn't exist already - primaryKey: 'conversationId' + primaryKey: 'conversationId', }); } diff --git a/api/models/schema/defaults.js b/api/models/schema/defaults.js index 5fbecc3a5d..13c2fd0d4a 100644 --- a/api/models/schema/defaults.js +++ b/api/models/schema/defaults.js @@ -3,156 +3,156 @@ const conversationPreset = { endpoint: { type: String, default: null, - required: true + required: true, }, // for azureOpenAI, openAI, chatGPTBrowser only model: { type: String, default: null, - required: false + required: false, }, // for azureOpenAI, openAI only chatGptLabel: { type: String, default: null, - required: false + required: false, }, // for google only modelLabel: { type: String, default: null, - required: false + required: false, }, promptPrefix: { type: String, default: null, - required: false + required: false, }, temperature: { type: Number, default: 1, - required: false + required: false, }, top_p: { type: Number, default: 1, - required: false + required: false, }, // for google only topP: { type: Number, default: 0.95, - required: false + required: false, }, topK: { type: Number, default: 40, - required: false + required: false, }, maxOutputTokens: { type: Number, default: 1024, - required: false + required: false, }, presence_penalty: { type: Number, default: 0, - required: false + required: false, }, frequency_penalty: { type: Number, default: 0, - required: false + required: false, }, // for bingai only jailbreak: { type: Boolean, - default: false + default: false, }, context: { type: String, - default: null + default: null, }, systemMessage: { type: String, - default: null + default: null, }, toneStyle: { type: String, - default: null - } + default: null, + }, }; const agentOptions = { model: { type: String, default: null, - required: false + required: false, }, // for azureOpenAI, openAI only chatGptLabel: { type: String, default: null, - required: false + required: false, }, // for google only modelLabel: { type: String, default: null, - required: false + required: false, }, promptPrefix: { type: String, default: null, - required: false + required: false, }, temperature: { type: Number, default: 1, - required: false + required: false, }, top_p: { type: Number, default: 1, - required: false + required: false, }, // for google only topP: { type: Number, default: 0.95, - required: false + required: false, }, topK: { type: Number, default: 40, - required: false + required: false, }, maxOutputTokens: { type: Number, default: 1024, - required: false + required: false, }, presence_penalty: { type: Number, default: 0, - required: false + required: false, }, frequency_penalty: { type: Number, default: 0, - required: false + required: false, }, context: { type: String, - default: null + default: null, }, systemMessage: { type: String, - default: null - } + default: null, + }, }; module.exports = { conversationPreset, - agentOptions + agentOptions, }; \ No newline at end of file diff --git a/api/models/schema/messageSchema.js b/api/models/schema/messageSchema.js index 2e367dc861..7754f34177 100644 --- a/api/models/schema/messageSchema.js +++ b/api/models/schema/messageSchema.js @@ -7,88 +7,88 @@ const messageSchema = mongoose.Schema( unique: true, required: true, index: true, - meiliIndex: true + meiliIndex: true, }, conversationId: { type: String, required: true, - meiliIndex: true + meiliIndex: true, }, model: { - type: String + type: String, }, conversationSignature: { - type: String + type: String, // required: true }, clientId: { - type: String + type: String, }, invocationId: { - type: String + type: String, }, parentMessageId: { - type: String + type: String, // required: true }, tokenCount: { - type: Number + type: Number, }, refinedTokenCount: { - type: Number + type: Number, }, sender: { type: String, required: true, - meiliIndex: true + meiliIndex: true, }, text: { type: String, required: true, - meiliIndex: true + meiliIndex: true, }, refinedMessageText: { - type: String + type: String, }, isCreatedByUser: { type: Boolean, required: true, - default: false + default: false, }, unfinished: { type: Boolean, - default: false + default: false, }, cancelled: { type: Boolean, - default: false + default: false, }, error: { type: Boolean, - default: false + default: false, }, _meiliIndex: { type: Boolean, required: false, select: false, - default: false + default: false, }, plugin: { latest: { type: String, - required: false + required: false, }, inputs: { type: [mongoose.Schema.Types.Mixed], - required: false + required: false, }, outputs: { type: String, - required: false - } - } + required: false, + }, + }, }, - { timestamps: true } + { timestamps: true }, ); if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) { @@ -96,7 +96,7 @@ if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) { host: process.env.MEILI_HOST, apiKey: process.env.MEILI_MASTER_KEY, indexName: 'messages', - primaryKey: 'messageId' + primaryKey: 'messageId', }); } diff --git a/api/models/schema/pluginAuthSchema.js b/api/models/schema/pluginAuthSchema.js index d846164b44..296f903337 100644 --- a/api/models/schema/pluginAuthSchema.js +++ b/api/models/schema/pluginAuthSchema.js @@ -8,17 +8,17 @@ const pluginAuthSchema = mongoose.Schema( }, value: { type: String, - required: true + required: true, }, userId: { type: String, - required: true + required: true, }, pluginKey: { type: String, - } + }, }, - { timestamps: true } + { timestamps: true }, ); const PluginAuth = mongoose.models.Plugin || mongoose.model('PluginAuth', pluginAuthSchema); diff --git a/api/models/schema/presetSchema.js b/api/models/schema/presetSchema.js index 54bd7c7d05..908811a0e7 100644 --- a/api/models/schema/presetSchema.js +++ b/api/models/schema/presetSchema.js @@ -6,26 +6,26 @@ const presetSchema = mongoose.Schema( type: String, unique: true, required: true, - index: true + index: true, }, title: { type: String, default: 'New Chat', - meiliIndex: true + meiliIndex: true, }, user: { type: String, - default: null + default: null, }, // google only examples: [{ type: mongoose.Schema.Types.Mixed }], ...conversationPreset, agentOptions: { type: mongoose.Schema.Types.Mixed, - default: null - } + default: null, + }, }, - { timestamps: true } + { timestamps: true }, ); const Preset = mongoose.models.Preset || mongoose.model('Preset', presetSchema); diff --git a/api/models/schema/tokenSchema.js b/api/models/schema/tokenSchema.js index 67fdf3e521..0f085dc1de 100644 --- a/api/models/schema/tokenSchema.js +++ b/api/models/schema/tokenSchema.js @@ -5,18 +5,18 @@ const tokenSchema = new Schema({ userId: { type: Schema.Types.ObjectId, required: true, - ref: 'user' + ref: 'user', }, token: { type: String, - required: true + required: true, }, createdAt: { type: Date, required: true, default: Date.now, - expires: 900 - } + expires: 900, + }, }); module.exports = mongoose.model('Token', tokenSchema); diff --git a/api/server/controllers/AuthController.js b/api/server/controllers/AuthController.js index 649ed56324..442af996ef 100644 --- a/api/server/controllers/AuthController.js +++ b/api/server/controllers/AuthController.js @@ -1,7 +1,7 @@ const { registerUser, requestPasswordReset, - resetPassword + resetPassword, } = require('../services/auth.service'); const isProduction = process.env.NODE_ENV === 'production'; @@ -16,7 +16,7 @@ const registrationController = async (req, res) => { res.cookie('token', token, { expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)), httpOnly: false, - secure: isProduction + secure: isProduction, }); res.status(status).send({ user }); } else { @@ -52,7 +52,7 @@ const resetPasswordController = async (req, res) => { const resetPasswordService = await resetPassword( req.body.userId, req.body.token, - req.body.password + req.body.password, ); if (resetPasswordService instanceof Error) { return res.status(400).json(resetPasswordService); @@ -120,5 +120,5 @@ module.exports = { // refreshController, registrationController, resetPasswordRequestController, - resetPasswordController + resetPasswordController, }; diff --git a/api/server/controllers/PluginController.js b/api/server/controllers/PluginController.js index 49843554c6..1f6d35064b 100644 --- a/api/server/controllers/PluginController.js +++ b/api/server/controllers/PluginController.js @@ -45,7 +45,7 @@ const getAvailablePluginsController = async (req, res) => { }); res.status(200).json(authenticatedPlugins); } - } + }, ); } catch (error) { res.status(500).json({ message: error.message }); @@ -53,5 +53,5 @@ const getAvailablePluginsController = async (req, res) => { }; module.exports = { - getAvailablePluginsController + getAvailablePluginsController, }; diff --git a/api/server/controllers/UserController.js b/api/server/controllers/UserController.js index 332fd3c474..21f03f686c 100644 --- a/api/server/controllers/UserController.js +++ b/api/server/controllers/UserController.js @@ -51,5 +51,5 @@ const updateUserPluginsController = async (req, res) => { module.exports = { getUserController, - updateUserPluginsController + updateUserPluginsController, }; diff --git a/api/server/controllers/auth/LoginController.js b/api/server/controllers/auth/LoginController.js index dc8544e323..dddcadf477 100644 --- a/api/server/controllers/auth/LoginController.js +++ b/api/server/controllers/auth/LoginController.js @@ -3,7 +3,7 @@ const User = require('../../../models/User'); const loginController = async (req, res) => { try { const user = await User.findById( - req.user._id + req.user._id, ); // If user doesn't exist, return error @@ -13,7 +13,7 @@ const loginController = async (req, res) => { const token = req.user.generateToken(); const expires = eval(process.env.SESSION_EXPIRY); - + // Add token to cookie res.cookie( 'token', @@ -21,8 +21,8 @@ const loginController = async (req, res) => { { expires: new Date(Date.now() + expires), httpOnly: false, - secure: process.env.NODE_ENV === 'production' - } + secure: process.env.NODE_ENV === 'production', + }, ); return res.status(200).send({ token, user }); @@ -35,5 +35,5 @@ const loginController = async (req, res) => { }; module.exports = { - loginController + loginController, }; \ No newline at end of file diff --git a/api/server/controllers/auth/LogoutController.js b/api/server/controllers/auth/LogoutController.js index e8aa48cdb9..c4561c0a41 100644 --- a/api/server/controllers/auth/LogoutController.js +++ b/api/server/controllers/auth/LogoutController.js @@ -17,5 +17,5 @@ const logoutController = async (req, res) => { }; module.exports = { - logoutController + logoutController, }; \ No newline at end of file diff --git a/api/server/index.js b/api/server/index.js index 9f71a66b42..aa9bcef980 100644 --- a/api/server/index.js +++ b/api/server/index.js @@ -58,7 +58,7 @@ config.validate(); // Validate the config app.use(session({ secret: process.env.OPENID_SESSION_SECRET, resave: false, - saveUninitialized: false + saveUninitialized: false, })); app.use(passport.session()); require('../strategies/openidStrategy'); @@ -86,7 +86,7 @@ config.validate(); // Validate the config app.listen(port, host, () => { if (host == '0.0.0.0') console.log( - `Server listening on all interface at port ${port}. Use http://localhost:${port} to access it` + `Server listening on all interface at port ${port}. Use http://localhost:${port} to access it`, ); else console.log(`Server listening at http://${host == '0.0.0.0' ? 'localhost' : host}:${port}`); diff --git a/api/server/routes/ask/addToCache.js b/api/server/routes/ask/addToCache.js index 3f07cdf83d..616c9d91b0 100644 --- a/api/server/routes/ask/addToCache.js +++ b/api/server/routes/ask/addToCache.js @@ -5,19 +5,19 @@ const addToCache = async ({ endpoint, endpointOption, userMessage, responseMessa try { const conversationsCache = new Keyv({ store: new KeyvFile({ filename: './data/cache.json' }), - namespace: 'chatgpt' // should be 'bing' for bing/sydney + namespace: 'chatgpt', // should be 'bing' for bing/sydney }); const { conversationId, messageId: userMessageId, parentMessageId: userParentMessageId, - text: userText + text: userText, } = userMessage; const { messageId: responseMessageId, parentMessageId: responseParentMessageId, - text: responseText + text: responseText, } = responseMessage; let conversation = await conversationsCache.get(conversationId); @@ -26,7 +26,7 @@ const addToCache = async ({ endpoint, endpointOption, userMessage, responseMessa if (!conversation) { conversation = { messages: [], - createdAt: Date.now() + createdAt: Date.now(), }; // isNewConversation = true; } @@ -43,14 +43,14 @@ const addToCache = async ({ endpoint, endpointOption, userMessage, responseMessa id: userMessageId, parentMessageId: userParentMessageId, role: 'User', - message: userText + message: userText, }; let _responseMessage = { id: responseMessageId, parentMessageId: responseParentMessageId, role: roles(endpointOption), - message: responseText + message: responseText, }; conversation.messages.push(_userMessage, _responseMessage); diff --git a/api/server/routes/ask/anthropic.js b/api/server/routes/ask/anthropic.js index 39d0318bff..c50aa97b32 100644 --- a/api/server/routes/ask/anthropic.js +++ b/api/server/routes/ask/anthropic.js @@ -27,8 +27,8 @@ router.post('/', requireJwtAuth, async (req, res) => { temperature: req.body?.temperature ?? 0.7, maxOutputTokens: req.body?.maxOutputTokens ?? 1024, topP: req.body?.topP ?? 0.7, - topK: req.body?.topK ?? 40 - } + topK: req.body?.topK ?? 40, + }, }; const conversationId = oldConversationId || crypto.randomUUID(); @@ -39,7 +39,7 @@ router.post('/', requireJwtAuth, async (req, res) => { conversationId, parentMessageId, req, - res + res, }); }); @@ -49,7 +49,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache, no-transform', 'Access-Control-Allow-Origin': '*', - 'X-Accel-Buffering': 'no' + 'X-Accel-Buffering': 'no', }); let userMessage; @@ -81,10 +81,10 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI text: partialText, unfinished: true, cancelled: false, - error: false + error: false, }); } - } + }, }); const abortController = new AbortController(); @@ -110,7 +110,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: responseMessage + responseMessage: responseMessage, }; }; @@ -132,10 +132,10 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI onProgress: progressCallback.call(null, { res, text, - parentMessageId: overrideParentMessageId || userMessageId + parentMessageId: overrideParentMessageId || userMessageId, }), onStart, - abortController + abortController, }); if (overrideParentMessageId) { @@ -146,7 +146,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI ...endpointOption, ...endpointOption.modelOptions, conversationId, - endpoint: 'anthropic' + endpoint: 'anthropic', }); await saveMessage(response); @@ -155,7 +155,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: response + responseMessage: response, }); res.end(); @@ -163,7 +163,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI const title = await titleConvo({ text, response }); await saveConvo(req.user.id, { conversationId, - title + title, }); } } catch (error) { @@ -176,7 +176,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI unfinished: false, cancelled: false, error: true, - text: error.message + text: error.message, }; await saveMessage(errorMessage); handleError(res, errorMessage); diff --git a/api/server/routes/ask/askBingAI.js b/api/server/routes/ask/askBingAI.js index 5e44f4b1bf..7a00ea79df 100644 --- a/api/server/routes/ask/askBingAI.js +++ b/api/server/routes/ask/askBingAI.js @@ -13,7 +13,7 @@ router.post('/', requireJwtAuth, async (req, res) => { messageId, overrideParentMessageId = null, parentMessageId, - conversationId: oldConversationId + conversationId: oldConversationId, } = req.body; if (text.length === 0) return handleError(res, { text: 'Prompt empty or too short' }); if (endpoint !== 'bingAI') return handleError(res, { text: 'Illegal request' }); @@ -29,7 +29,7 @@ router.post('/', requireJwtAuth, async (req, res) => { text, parentMessageId: userParentMessageId, conversationId, - isCreatedByUser: true + isCreatedByUser: true, }; // build endpoint option @@ -41,7 +41,7 @@ router.post('/', requireJwtAuth, async (req, res) => { systemMessage: req.body?.systemMessage ?? null, context: req.body?.context ?? null, toneStyle: req.body?.toneStyle ?? 'creative', - token: req.body?.token ?? null + token: req.body?.token ?? null, }; else endpointOption = { @@ -52,13 +52,13 @@ router.post('/', requireJwtAuth, async (req, res) => { clientId: req.body?.clientId ?? null, invocationId: req.body?.invocationId ?? null, toneStyle: req.body?.toneStyle ?? 'creative', - token: req.body?.token ?? null + token: req.body?.token ?? null, }; console.log('ask log', { userMessage, endpointOption, - conversationId + conversationId, }); if (!overrideParentMessageId) { @@ -67,7 +67,7 @@ router.post('/', requireJwtAuth, async (req, res) => { ...userMessage, ...endpointOption, conversationId, - endpoint + endpoint, }); } @@ -80,7 +80,7 @@ router.post('/', requireJwtAuth, async (req, res) => { preSendRequest: true, overrideParentMessageId, req, - res + res, }); }); @@ -92,7 +92,7 @@ const ask = async ({ preSendRequest = true, overrideParentMessageId = null, req, - res + res, }) => { let { text, parentMessageId: userParentMessageId, messageId: userMessageId } = userMessage; @@ -103,7 +103,7 @@ const ask = async ({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache, no-transform', 'Access-Control-Allow-Origin': '*', - 'X-Accel-Buffering': 'no' + 'X-Accel-Buffering': 'no', }); if (preSendRequest) sendMessage(res, { message: userMessage, created: true }); @@ -123,10 +123,10 @@ const ask = async ({ text: text, unfinished: true, cancelled: false, - error: false + error: false, }); } - } + }, }); const abortController = new AbortController(); let bingConversationId = null; @@ -142,9 +142,9 @@ const ask = async ({ onProgress: progressCallback.call(null, { res, text, - parentMessageId: overrideParentMessageId || userMessageId + parentMessageId: overrideParentMessageId || userMessageId, }), - abortController + abortController, }); console.log('BING RESPONSE', response); @@ -173,7 +173,7 @@ const ask = async ({ response.details.suggestedResponses.map((s) => s.text), unfinished: false, cancelled: false, - error: false + error: false, }; await saveMessage(responseMessage); @@ -199,7 +199,7 @@ const ask = async ({ await saveMessage({ ...userMessage, messageId: userMessageId, - newMessageId: newUserMessageId + newMessageId: newUserMessageId, }); userMessageId = newUserMessageId; @@ -208,19 +208,19 @@ const ask = async ({ final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: responseMessage + responseMessage: responseMessage, }); res.end(); if (userParentMessageId == '00000000-0000-0000-0000-000000000000') { const title = await titleConvoBing({ text, - response: responseMessage + response: responseMessage, }); await saveConvo(req.user.id, { conversationId: conversationId, - title + title, }); } } catch (error) { @@ -233,7 +233,7 @@ const ask = async ({ unfinished: false, cancelled: false, error: true, - text: error.message + text: error.message, }; await saveMessage(errorMessage); handleError(res, errorMessage); diff --git a/api/server/routes/ask/askChatGPTBrowser.js b/api/server/routes/ask/askChatGPTBrowser.js index 9d4050c96f..9e4e8aacef 100644 --- a/api/server/routes/ask/askChatGPTBrowser.js +++ b/api/server/routes/ask/askChatGPTBrowser.js @@ -13,7 +13,7 @@ router.post('/', requireJwtAuth, async (req, res) => { text, overrideParentMessageId = null, parentMessageId, - conversationId: oldConversationId + conversationId: oldConversationId, } = req.body; if (text.length === 0) return handleError(res, { text: 'Prompt empty or too short' }); if (endpoint !== 'chatGPTBrowser') return handleError(res, { text: 'Illegal request' }); @@ -29,13 +29,13 @@ router.post('/', requireJwtAuth, async (req, res) => { text, parentMessageId: userParentMessageId, conversationId, - isCreatedByUser: true + isCreatedByUser: true, }; // build endpoint option const endpointOption = { model: req.body?.model ?? 'text-davinci-002-render-sha', - token: req.body?.token ?? null + token: req.body?.token ?? null, }; // const availableModels = getChatGPTBrowserModels(); @@ -45,7 +45,7 @@ router.post('/', requireJwtAuth, async (req, res) => { console.log('ask log', { userMessage, endpointOption, - conversationId + conversationId, }); if (!overrideParentMessageId) { @@ -54,7 +54,7 @@ router.post('/', requireJwtAuth, async (req, res) => { ...userMessage, ...endpointOption, conversationId, - endpoint + endpoint, }); } @@ -67,7 +67,7 @@ router.post('/', requireJwtAuth, async (req, res) => { preSendRequest: true, overrideParentMessageId, req, - res + res, }); }); @@ -78,7 +78,7 @@ const ask = async ({ conversationId, overrideParentMessageId = null, req, - res + res, }) => { let { text, parentMessageId: userParentMessageId, messageId: userMessageId } = userMessage; const userId = req.user.id; @@ -88,7 +88,7 @@ const ask = async ({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache, no-transform', 'Access-Control-Allow-Origin': '*', - 'X-Accel-Buffering': 'no' + 'X-Accel-Buffering': 'no', }); let responseMessageId = crypto.randomUUID(); @@ -108,10 +108,10 @@ const ask = async ({ text: text, unfinished: true, cancelled: false, - error: false + error: false, }); } - } + }, }); getPartialMessage = getPartialText; @@ -134,9 +134,9 @@ const ask = async ({ sendMessage(res, { message: { ...userMessage, conversationId: data.conversation_id }, - created: true + created: true, }); - } + }, }); console.log('CLIENT RESPONSE', response); @@ -157,7 +157,7 @@ const ask = async ({ sender: endpointOption?.chatGptLabel || 'ChatGPT', unfinished: false, cancelled: false, - error: false + error: false, }; await saveMessage(responseMessage); @@ -173,13 +173,13 @@ const ask = async ({ conversationUpdate = { ...conversationUpdate, conversationId: conversationId, - newConversationId: newConversationId + newConversationId: newConversationId, }; } else { // create new conversation conversationUpdate = { ...conversationUpdate, - ...endpointOption + ...endpointOption, }; } @@ -195,7 +195,7 @@ const ask = async ({ await saveMessage({ ...userMessage, messageId: userMessageId, - newMessageId: newUserMassageId + newMessageId: newUserMassageId, }); userMessageId = newUserMassageId; @@ -204,7 +204,7 @@ const ask = async ({ final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: responseMessage + responseMessage: responseMessage, }); res.end(); @@ -213,7 +213,7 @@ const ask = async ({ const title = await response.details.title; await saveConvo(req.user.id, { conversationId: conversationId, - title + title, }); } } catch (error) { @@ -225,7 +225,7 @@ const ask = async ({ unfinished: false, cancelled: false, // error: true, - text: `${getPartialMessage() ?? ''}\n\nError message: "${error.message}"` + text: `${getPartialMessage() ?? ''}\n\nError message: "${error.message}"`, }; await saveMessage(errorMessage); handleError(res, errorMessage); diff --git a/api/server/routes/ask/google.js b/api/server/routes/ask/google.js index 471bee295e..5d5a163766 100644 --- a/api/server/routes/ask/google.js +++ b/api/server/routes/ask/google.js @@ -23,13 +23,13 @@ router.post('/', requireJwtAuth, async (req, res) => { temperature: req.body?.temperature ?? 0.2, maxOutputTokens: req.body?.maxOutputTokens ?? 1024, topP: req.body?.topP ?? 0.95, - topK: req.body?.topK ?? 40 - } + topK: req.body?.topK ?? 40, + }, }; const availableModels = ['chat-bison', 'text-bison', 'codechat-bison']; if (availableModels.find((model) => model === endpointOption.modelOptions.model) === undefined) { - return handleError(res, { text: `Illegal request: model` }); + return handleError(res, { text: 'Illegal request: model' }); } const conversationId = oldConversationId || crypto.randomUUID(); @@ -41,7 +41,7 @@ router.post('/', requireJwtAuth, async (req, res) => { conversationId, parentMessageId, req, - res + res, }); }); @@ -51,7 +51,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache, no-transform', 'Access-Control-Allow-Origin': '*', - 'X-Accel-Buffering': 'no' + 'X-Accel-Buffering': 'no', }); let userMessage; let userMessageId; @@ -84,10 +84,10 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI text: partialText, unfinished: true, cancelled: false, - error: false + error: false, }); } - } + }, }); const abortController = new AbortController(); @@ -104,14 +104,14 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI key = require('../../../data/auth.json'); } } catch (e) { - console.log("No 'auth.json' file (service account key) found in /api/data/ for PaLM models"); + console.log('No \'auth.json\' file (service account key) found in /api/data/ for PaLM models'); } const clientOptions = { // debug: true, // for testing reverseProxyUrl: process.env.GOOGLE_REVERSE_PROXY || null, proxy: process.env.PROXY || null, - ...endpointOption + ...endpointOption, }; const client = new GoogleClient(key, clientOptions); @@ -125,9 +125,9 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI onProgress: progressCallback.call(null, { res, text, - parentMessageId: overrideParentMessageId || userMessageId + parentMessageId: overrideParentMessageId || userMessageId, }), - abortController + abortController, }); if (overrideParentMessageId) { @@ -138,7 +138,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI ...endpointOption, ...endpointOption.modelOptions, conversationId, - endpoint: 'google' + endpoint: 'google', }); await saveMessage(response); @@ -147,7 +147,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: response + responseMessage: response, }); res.end(); @@ -155,7 +155,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI const title = await titleConvo({ text, response }); await saveConvo(req.user.id, { conversationId, - title + title, }); } } catch (error) { @@ -168,7 +168,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, conversationI unfinished: false, cancelled: false, error: true, - text: error.message + text: error.message, }; await saveMessage(errorMessage); handleError(res, errorMessage); diff --git a/api/server/routes/ask/gptPlugins.js b/api/server/routes/ask/gptPlugins.js index 4562cdb2c7..c54129f477 100644 --- a/api/server/routes/ask/gptPlugins.js +++ b/api/server/routes/ask/gptPlugins.js @@ -8,7 +8,7 @@ const { sendMessage, createOnProgress, formatSteps, - formatAction + formatAction, } = require('./handlers'); const requireJwtAuth = require('../../../middleware/requireJwtAuth'); @@ -44,12 +44,12 @@ router.post('/', requireJwtAuth, async (req, res) => { temperature: req.body?.temperature ?? 0, top_p: req.body?.top_p ?? 1, presence_penalty: req.body?.presence_penalty ?? 0, - frequency_penalty: req.body?.frequency_penalty ?? 0 + frequency_penalty: req.body?.frequency_penalty ?? 0, }, agentOptions: { ...agentOptions, // agent: 'functions' - } + }, }; console.log('ask log'); @@ -63,7 +63,7 @@ router.post('/', requireJwtAuth, async (req, res) => { conversationId, parentMessageId, req, - res + res, }); }); @@ -73,7 +73,7 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache, no-transform', 'Access-Control-Allow-Origin': '*', - 'X-Accel-Buffering': 'no' + 'X-Accel-Buffering': 'no', }); let userMessage; let userMessageId; @@ -87,7 +87,7 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con loading: true, inputs: [], latest: null, - outputs: null + outputs: null, }; try { @@ -119,10 +119,10 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con model: endpointOption.modelOptions.model, unfinished: true, cancelled: false, - error: false + error: false, }); } - } + }, }); const abortController = new AbortController(); @@ -149,7 +149,7 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: responseMessage + responseMessage: responseMessage, }; }; @@ -164,7 +164,7 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con endpoint, reverseProxyUrl: process.env.OPENAI_REVERSE_PROXY || null, proxy: process.env.PROXY || null, - ...endpointOption + ...endpointOption, }; let openAIApiKey = req.body?.token ?? process.env.OPENAI_API_KEY; @@ -211,9 +211,9 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con res, text, plugin, - parentMessageId: overrideParentMessageId || userMessageId + parentMessageId: overrideParentMessageId || userMessageId, }), - abortController + abortController, }); if (overrideParentMessageId) { @@ -230,7 +230,7 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: response + responseMessage: response, }); res.end(); @@ -243,7 +243,7 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con }); await saveConvo(req.user.id, { conversationId: conversationId, - title + title, }); } } catch (error) { @@ -256,7 +256,7 @@ const ask = async ({ text, endpoint, endpointOption, parentMessageId = null, con unfinished: false, cancelled: false, error: true, - text: error.message + text: error.message, }; await saveMessage(errorMessage); handleError(res, errorMessage); diff --git a/api/server/routes/ask/handlers.js b/api/server/routes/ask/handlers.js index d709512c24..c99432a16c 100644 --- a/api/server/routes/ask/handlers.js +++ b/api/server/routes/ask/handlers.js @@ -134,7 +134,7 @@ function formatAction(action) { input: getString(action.toolInput), thought: action.log.includes('Thought: ') ? action.log.split('\n')[0].replace('Thought: ', '') - : action.log.split('\n')[0] + : action.log.split('\n')[0], }; formattedAction.thought = getString(formattedAction.thought); @@ -161,5 +161,5 @@ module.exports = { createOnProgress, handleText, formatSteps, - formatAction + formatAction, }; \ No newline at end of file diff --git a/api/server/routes/ask/openAI.js b/api/server/routes/ask/openAI.js index d644002d0d..03795423d1 100644 --- a/api/server/routes/ask/openAI.js +++ b/api/server/routes/ask/openAI.js @@ -31,8 +31,8 @@ router.post('/', requireJwtAuth, async (req, res) => { temperature: req.body?.temperature ?? 1, top_p: req.body?.top_p ?? 1, presence_penalty: req.body?.presence_penalty ?? 0, - frequency_penalty: req.body?.frequency_penalty ?? 0 - } + frequency_penalty: req.body?.frequency_penalty ?? 0, + }, }; console.log('ask log'); @@ -46,7 +46,7 @@ router.post('/', requireJwtAuth, async (req, res) => { parentMessageId, endpoint, req, - res + res, }); }); @@ -56,7 +56,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache, no-transform', 'Access-Control-Allow-Origin': '*', - 'X-Accel-Buffering': 'no' + 'X-Accel-Buffering': 'no', }); let userMessage; let userMessageId; @@ -90,10 +90,10 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con model: endpointOption.modelOptions.model, unfinished: true, cancelled: false, - error: false + error: false, }); } - } + }, }); const abortController = new AbortController(); @@ -119,7 +119,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: responseMessage + responseMessage: responseMessage, }; }; @@ -135,7 +135,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con reverseProxyUrl: process.env.OPENAI_REVERSE_PROXY || null, proxy: process.env.PROXY || null, endpoint, - ...endpointOption + ...endpointOption, }; let openAIApiKey = req.body?.token ?? process.env.OPENAI_API_KEY; @@ -157,9 +157,9 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con onProgress: progressCallback.call(null, { res, text, - parentMessageId: overrideParentMessageId || userMessageId + parentMessageId: overrideParentMessageId || userMessageId, }), - abortController + abortController, }); if (overrideParentMessageId) { @@ -174,7 +174,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con final: true, conversation: await getConvo(req.user.id, conversationId), requestMessage: userMessage, - responseMessage: response + responseMessage: response, }); res.end(); @@ -183,11 +183,11 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con text, response, openAIApiKey, - azure: endpoint === 'azureOpenAI' + azure: endpoint === 'azureOpenAI', }); await saveConvo(req.user.id, { conversationId, - title + title, }); } } catch (error) { @@ -204,7 +204,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con unfinished: false, cancelled: false, error: true, - text: error.message + text: error.message, }; await saveMessage(errorMessage); handleError(res, errorMessage); diff --git a/api/server/routes/auth.js b/api/server/routes/auth.js index e4f7f47a55..95df18f2da 100644 --- a/api/server/routes/auth.js +++ b/api/server/routes/auth.js @@ -3,7 +3,7 @@ const { resetPasswordRequestController, resetPasswordController, // refreshController, - registrationController + registrationController, } = require('../controllers/AuthController'); const { loginController } = require('../controllers/auth/LoginController'); const { logoutController } = require('../controllers/auth/LogoutController'); diff --git a/api/server/routes/config.js b/api/server/routes/config.js index bbb5906035..3bb04b4140 100644 --- a/api/server/routes/config.js +++ b/api/server/routes/config.js @@ -5,9 +5,9 @@ router.get('/', async function (req, res) { try { const appTitle = process.env.APP_TITLE || 'LibreChat'; const googleLoginEnabled = !!process.env.GOOGLE_CLIENT_ID && !!process.env.GOOGLE_CLIENT_SECRET; - const openidLoginEnabled = !!process.env.OPENID_CLIENT_ID - && !!process.env.OPENID_CLIENT_SECRET - && !!process.env.OPENID_ISSUER + const openidLoginEnabled = !!process.env.OPENID_CLIENT_ID + && !!process.env.OPENID_CLIENT_SECRET + && !!process.env.OPENID_ISSUER && !!process.env.OPENID_SESSION_SECRET; const openidLabel = process.env.OPENID_BUTTON_LABEL || 'Login with OpenID'; const openidImageUrl = process.env.OPENID_IMAGE_URL; @@ -16,7 +16,7 @@ router.get('/', async function (req, res) { const serverDomain = process.env.DOMAIN_SERVER || 'http://localhost:3080'; const registrationEnabled = process.env.ALLOW_REGISTRATION === 'true'; const socialLoginEnabled = process.env.ALLOW_SOCIAL_LOGIN === 'true'; - + return res.status(200).send({ appTitle, googleLoginEnabled, @@ -27,12 +27,12 @@ router.get('/', async function (req, res) { discordLoginEnabled, serverDomain, registrationEnabled, - socialLoginEnabled + socialLoginEnabled, }); - + } catch (err) { console.error(err); - return res.status(500).send({error: err.message}); + return res.status(500).send({ error: err.message }); } }); diff --git a/api/server/routes/endpoints.js b/api/server/routes/endpoints.js index bcd3c36dd4..1b54b77fa3 100644 --- a/api/server/routes/endpoints.js +++ b/api/server/routes/endpoints.js @@ -72,13 +72,13 @@ router.get('/', async function (req, res) { const chatGPTBrowser = process.env.CHATGPT_TOKEN ? { userProvide: process.env.CHATGPT_TOKEN == 'user_provided', - availableModels: getChatGPTBrowserModels() + availableModels: getChatGPTBrowserModels(), } : false; const anthropic = process.env.ANTHROPIC_API_KEY ? { userProvide: process.env.ANTHROPIC_API_KEY == 'user_provided', - availableModels: getAnthropicModels() + availableModels: getAnthropicModels(), } : false; diff --git a/api/server/routes/index.js b/api/server/routes/index.js index f41f5c3baa..18d2a44fc4 100644 --- a/api/server/routes/index.js +++ b/api/server/routes/index.js @@ -25,5 +25,5 @@ module.exports = { tokenizer, endpoints, plugins, - config + config, }; diff --git a/api/server/routes/oauth.js b/api/server/routes/oauth.js index d57ceb0516..bd82f4cb4e 100644 --- a/api/server/routes/oauth.js +++ b/api/server/routes/oauth.js @@ -12,8 +12,8 @@ router.get( '/google', passport.authenticate('google', { scope: ['openid', 'profile', 'email'], - session: false - }) + session: false, + }), ); router.get( @@ -22,25 +22,25 @@ router.get( failureRedirect: `${domains.client}/login`, failureMessage: true, session: false, - scope: ['openid', 'profile', 'email'] + scope: ['openid', 'profile', 'email'], }), (req, res) => { const token = req.user.generateToken(); res.cookie('token', token, { expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)), httpOnly: false, - secure: isProduction + secure: isProduction, }); res.redirect(domains.client); - } + }, ); router.get( '/facebook', passport.authenticate('facebook', { scope: ['public_profile', 'email'], - session: false - }) + session: false, + }), ); router.get( @@ -49,24 +49,24 @@ router.get( failureRedirect: `${domains.client}/login`, failureMessage: true, session: false, - scope: ['public_profile', 'email'] + scope: ['public_profile', 'email'], }), (req, res) => { const token = req.user.generateToken(); res.cookie('token', token, { expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)), httpOnly: false, - secure: isProduction + secure: isProduction, }); res.redirect(domains.client); - } + }, ); router.get( '/openid', passport.authenticate('openid', { - session: false - }) + session: false, + }), ); router.get( @@ -74,26 +74,25 @@ router.get( passport.authenticate('openid', { failureRedirect: `${domains.client}/login`, failureMessage: true, - session: false + session: false, }), (req, res) => { const token = req.user.generateToken(); res.cookie('token', token, { expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)), httpOnly: false, - secure: isProduction + secure: isProduction, }); res.redirect(domains.client); - } + }, ); - router.get( '/github', passport.authenticate('github', { scope: ['user:email', 'read:user'], - session: false - }) + session: false, + }), ); router.get( @@ -102,26 +101,25 @@ router.get( failureRedirect: `${domains.client}/login`, failureMessage: true, session: false, - scope: ['user:email', 'read:user'] + scope: ['user:email', 'read:user'], }), (req, res) => { const token = req.user.generateToken(); res.cookie('token', token, { expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)), httpOnly: false, - secure: isProduction + secure: isProduction, }); res.redirect(domains.client); - } + }, ); - router.get( '/discord', passport.authenticate('discord', { scope: ['identify', 'email'], - session: false - }) + session: false, + }), ); router.get( @@ -130,17 +128,17 @@ router.get( failureRedirect: `${domains.client}/login`, failureMessage: true, session: false, - scope: ['identify', 'email'] + scope: ['identify', 'email'], }), (req, res) => { const token = req.user.generateToken(); res.cookie('token', token, { expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)), httpOnly: false, - secure: isProduction + secure: isProduction, }); res.redirect(domains.client); - } + }, ); module.exports = router; diff --git a/api/server/routes/prompts.js b/api/server/routes/prompts.js index 84ff935f00..753feb262a 100644 --- a/api/server/routes/prompts.js +++ b/api/server/routes/prompts.js @@ -1,6 +1,6 @@ const express = require('express'); const router = express.Router(); -const { savePrompt, getPrompts, deletePrompts } = require('../../models/Prompt'); +const { getPrompts } = require('../../models/Prompt'); router.get('/', async (req, res) => { let filter = {}; diff --git a/api/server/routes/search.js b/api/server/routes/search.js index 50375d8c12..aa8d2abeac 100644 --- a/api/server/routes/search.js +++ b/api/server/routes/search.js @@ -42,16 +42,16 @@ router.get('/', requireJwtAuth, async function (req, res) { { attributesToHighlight: ['text'], highlightPreTag: '**', - highlightPostTag: '**' + highlightPostTag: '**', }, - true + true, ) ).hits.map((message) => { const { _formatted, ...rest } = message; return { ...rest, searchResult: true, - text: _formatted.text + text: _formatted.text, }; }); const titles = (await Conversation.meiliSearch(q)).hits; @@ -111,7 +111,7 @@ router.get('/enable', async function (req, res) { try { const client = new MeiliSearch({ host: process.env.MEILI_HOST, - apiKey: process.env.MEILI_MASTER_KEY + apiKey: process.env.MEILI_MASTER_KEY, }); const { status } = await client.health(); diff --git a/api/server/services/PluginService.js b/api/server/services/PluginService.js index 1be98638d6..7a4041c37a 100644 --- a/api/server/services/PluginService.js +++ b/api/server/services/PluginService.js @@ -47,7 +47,7 @@ const updateUserPluginAuth = async (userId, authField, pluginKey, value) => { if (pluginAuth) { const pluginAuth = await PluginAuth.updateOne( { userId, authField }, - { $set: { value: encryptedValue } } + { $set: { value: encryptedValue } }, ); return pluginAuth; } else { @@ -55,7 +55,7 @@ const updateUserPluginAuth = async (userId, authField, pluginKey, value) => { userId, authField, value: encryptedValue, - pluginKey + pluginKey, }); newPluginAuth.save(); return newPluginAuth; @@ -79,5 +79,5 @@ const deleteUserPluginAuth = async (userId, authField) => { module.exports = { getUserPluginAuthValue, updateUserPluginAuth, - deleteUserPluginAuth + deleteUserPluginAuth, }; diff --git a/api/server/services/UserService.js b/api/server/services/UserService.js index 21e9baadbe..ba037be8e0 100644 --- a/api/server/services/UserService.js +++ b/api/server/services/UserService.js @@ -5,13 +5,13 @@ const updateUserPluginsService = async (user, pluginKey, action) => { if (action === 'install') { const response = await User.updateOne( { _id: user._id }, - { $set: { plugins: [...user.plugins, pluginKey] } } + { $set: { plugins: [...user.plugins, pluginKey] } }, ); return response; } else if (action === 'uninstall') { const response = await User.updateOne( { _id: user._id }, - { $set: { plugins: user.plugins.filter((plugin) => plugin !== pluginKey) } } + { $set: { plugins: user.plugins.filter((plugin) => plugin !== pluginKey) } }, ); return response; } diff --git a/api/server/services/auth.service.js b/api/server/services/auth.service.js index 00e8578e94..71bef1a40f 100644 --- a/api/server/services/auth.service.js +++ b/api/server/services/auth.service.js @@ -18,7 +18,7 @@ const logoutUser = async (user, refreshToken) => { try { const userFound = await User.findById(user._id); const tokenIndex = userFound.refreshToken.findIndex( - (item) => item.refreshToken === refreshToken + (item) => item.refreshToken === refreshToken, ); if (tokenIndex !== -1) { @@ -45,7 +45,7 @@ const registerUser = async (user) => { console.info( 'Route: register - Joi Validation Error', { name: 'Request params:', value: user }, - { name: 'Validation error:', value: error.details } + { name: 'Validation error:', value: error.details }, ); return { status: 422, message: error.details[0].message }; @@ -60,7 +60,7 @@ const registerUser = async (user) => { console.info( 'Register User - Email in use', { name: 'Request params:', value: user }, - { name: 'Existing user:', value: existingUser } + { name: 'Existing user:', value: existingUser }, ); // Sleep for 1 second @@ -80,7 +80,7 @@ const registerUser = async (user) => { username, name, avatar: null, - role: isFirstRegisteredUser ? 'ADMIN' : 'USER' + role: isFirstRegisteredUser ? 'ADMIN' : 'USER', }); // todo: implement refresh token @@ -118,7 +118,7 @@ const requestPasswordReset = async (email) => { await new Token({ userId: user._id, token: hash, - createdAt: Date.now() + createdAt: Date.now(), }).save(); const link = `${domains.client}/reset-password?token=${resetToken}&userId=${user._id}`; @@ -128,9 +128,9 @@ const requestPasswordReset = async (email) => { 'Password Reset Request', { name: user.name, - link: link + link: link, }, - './template/requestResetPassword.handlebars' + './template/requestResetPassword.handlebars', ); return { link }; }; @@ -166,9 +166,9 @@ const resetPassword = async (userId, token, password) => { user.email, 'Password Reset Successfully', { - name: user.name + name: user.name, }, - './template/resetPassword.handlebars' + './template/resetPassword.handlebars', ); await passwordResetToken.deleteOne(); @@ -180,5 +180,5 @@ module.exports = { registerUser, logoutUser, requestPasswordReset, - resetPassword + resetPassword, }; diff --git a/api/strategies/discordStrategy.js b/api/strategies/discordStrategy.js index 040453d9cd..a2d01b60c7 100644 --- a/api/strategies/discordStrategy.js +++ b/api/strategies/discordStrategy.js @@ -10,7 +10,7 @@ const discordLogin = new DiscordStrategy( clientSecret: process.env.DISCORD_CLIENT_SECRET, callbackURL: `${domains.server}${process.env.DISCORD_CALLBACK_URL}`, scope: ['identify', 'email'], // Request scopes - authorizationURL: 'https://discord.com/api/oauth2/authorize?prompt=none' // Add the prompt query parameter + authorizationURL: 'https://discord.com/api/oauth2/authorize?prompt=none', // Add the prompt query parameter }, async (accessToken, refreshToken, profile, cb) => { try { @@ -37,7 +37,7 @@ const discordLogin = new DiscordStrategy( username: profile.username, email, name: profile.global_name, - avatar: avatarURL + avatar: avatarURL, }); cb(null, newUser); @@ -45,7 +45,7 @@ const discordLogin = new DiscordStrategy( console.error(err); cb(err); } - } + }, ); passport.use(discordLogin); diff --git a/api/strategies/facebookStrategy.js b/api/strategies/facebookStrategy.js index fde968ada7..f7700fd51e 100644 --- a/api/strategies/facebookStrategy.js +++ b/api/strategies/facebookStrategy.js @@ -10,7 +10,7 @@ const facebookLogin = new FacebookStrategy( clientID: process.env.FACEBOOK_APP_ID, clientSecret: process.env.FACEBOOK_SECRET, callbackURL: `${domains.server}${process.env.FACEBOOK_CALLBACK_URL}`, - proxy: true + proxy: true, // profileFields: [ // 'id', // 'email', @@ -46,14 +46,14 @@ const facebookLogin = new FacebookStrategy( username: profile.name.givenName + profile.name.familyName, email: profile.emails[0].value, name: profile.displayName, - avatar: profile.photos[0].value + avatar: profile.photos[0].value, }).save(); done(null, newUser); } catch (err) { console.log(err); } - } + }, ); passport.use(facebookLogin); diff --git a/api/strategies/githubStrategy.js b/api/strategies/githubStrategy.js index 57578a26bb..62e6075b1e 100644 --- a/api/strategies/githubStrategy.js +++ b/api/strategies/githubStrategy.js @@ -12,7 +12,7 @@ const githubLogin = new GitHubStrategy( clientSecret: process.env.GITHUB_CLIENT_SECRET, callbackURL: `${domains.server}${process.env.GITHUB_CALLBACK_URL}`, proxy: false, - scope: ['user:email'] // Request email scope + scope: ['user:email'], // Request email scope }, async (accessToken, refreshToken, profile, cb) => { try { @@ -33,7 +33,7 @@ const githubLogin = new GitHubStrategy( email, emailVerified: profile.emails[0].verified, name: profile.displayName, - avatar: profile.photos[0].value + avatar: profile.photos[0].value, }).save(); cb(null, newUser); @@ -41,7 +41,7 @@ const githubLogin = new GitHubStrategy( console.error(err); cb(err); } - } + }, ); passport.use(githubLogin); diff --git a/api/strategies/googleStrategy.js b/api/strategies/googleStrategy.js index d9396e926a..ff6e07f0b6 100644 --- a/api/strategies/googleStrategy.js +++ b/api/strategies/googleStrategy.js @@ -11,7 +11,7 @@ const googleLogin = new GoogleStrategy( clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: `${domains.server}${process.env.GOOGLE_CALLBACK_URL}`, - proxy: true + proxy: true, }, async (accessToken, refreshToken, profile, cb) => { try { @@ -31,13 +31,13 @@ const googleLogin = new GoogleStrategy( email: profile.emails[0].value, emailVerified: profile.emails[0].verified, name: `${profile.name.givenName} ${profile.name.familyName}`, - avatar: profile.photos[0].value + avatar: profile.photos[0].value, }).save(); cb(null, newUser); } catch (err) { console.log(err); } - } + }, ); passport.use(googleLogin); diff --git a/api/strategies/jwtStrategy.js b/api/strategies/jwtStrategy.js index 3593f3cd8c..8d1aeb9b8f 100644 --- a/api/strategies/jwtStrategy.js +++ b/api/strategies/jwtStrategy.js @@ -6,7 +6,7 @@ const User = require('../models/User'); const jwtLogin = new JwtStrategy( { jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), - secretOrKey: process.env.JWT_SECRET + secretOrKey: process.env.JWT_SECRET, }, async (payload, done) => { try { @@ -20,7 +20,7 @@ const jwtLogin = new JwtStrategy( } catch (err) { done(err, false); } - } + }, ); passport.use(jwtLogin); diff --git a/api/strategies/localStrategy.js b/api/strategies/localStrategy.js index 108b953b00..e225cef32c 100644 --- a/api/strategies/localStrategy.js +++ b/api/strategies/localStrategy.js @@ -10,14 +10,14 @@ const passportLogin = new PassportLocalStrategy( usernameField: 'email', passwordField: 'password', session: false, - passReqToCallback: true + passReqToCallback: true, }, async (req, email, password, done) => { const { error } = loginSchema.validate(req.body); if (error) { log({ title: 'Passport Local Strategy - Validation Error', - parameters: [{ name: 'req.body', value: req.body }] + parameters: [{ name: 'req.body', value: req.body }], }); return done(null, false, { message: error.details[0].message }); } @@ -27,7 +27,7 @@ const passportLogin = new PassportLocalStrategy( if (!user) { log({ title: 'Passport Local Strategy - User Not Found', - parameters: [{ name: 'email', value: email }] + parameters: [{ name: 'email', value: email }], }); return done(null, false, { message: 'Email does not exists.' }); } @@ -36,14 +36,14 @@ const passportLogin = new PassportLocalStrategy( if (err) { log({ title: 'Passport Local Strategy - Compare password error', - parameters: [{ name: 'error', value: err }] + parameters: [{ name: 'error', value: err }], }); return done(err); } if (!isMatch) { log({ title: 'Passport Local Strategy - Password does not match', - parameters: [{ name: 'isMatch', value: isMatch }] + parameters: [{ name: 'isMatch', value: isMatch }], }); return done(null, false, { message: 'Incorrect password.' }); } @@ -53,7 +53,7 @@ const passportLogin = new PassportLocalStrategy( } catch (err) { return done(err); } - } + }, ); passport.use(passportLogin); diff --git a/api/strategies/openidStrategy.js b/api/strategies/openidStrategy.js index 65b0a3da5c..6d2511b4c6 100644 --- a/api/strategies/openidStrategy.js +++ b/api/strategies/openidStrategy.js @@ -1,5 +1,4 @@ const passport = require('passport'); -const jwt = require('jsonwebtoken'); const { Issuer, Strategy: OpenIDStrategy } = require('openid-client'); const axios = require('axios'); const fs = require('fs'); @@ -20,11 +19,11 @@ const downloadImage = async (url, imagePath, accessToken) => { try { const response = await axios.get(url, { headers: { - 'Authorization': `Bearer ${accessToken}` + 'Authorization': `Bearer ${accessToken}`, }, - responseType: 'arraybuffer' + responseType: 'arraybuffer', }); - + fs.mkdirSync(path.dirname(imagePath), { recursive: true }); fs.writeFileSync(imagePath, response.data); @@ -42,15 +41,15 @@ Issuer.discover(process.env.OPENID_ISSUER) const client = new issuer.Client({ client_id: process.env.OPENID_CLIENT_ID, client_secret: process.env.OPENID_CLIENT_SECRET, - redirect_uris: [domains.server + process.env.OPENID_CALLBACK_URL] + redirect_uris: [domains.server + process.env.OPENID_CALLBACK_URL], }); const openidLogin = new OpenIDStrategy( { client, params: { - scope: process.env.OPENID_SCOPE - } + scope: process.env.OPENID_SCOPE, + }, }, async (tokenset, userinfo, done) => { try { @@ -68,7 +67,7 @@ Issuer.discover(process.env.OPENID_ISSUER) } else if (userinfo.family_name) { fullName = userinfo.family_name; } - + if (!user) { user = new User({ provider: 'openid', @@ -76,7 +75,7 @@ Issuer.discover(process.env.OPENID_ISSUER) username: userinfo.given_name || '', email: userinfo.email || '', emailVerified: userinfo.email_verified || false, - name: fullName + name: fullName, }); } else { user.provider = 'openid'; @@ -105,14 +104,14 @@ Issuer.discover(process.env.OPENID_ISSUER) } else { user.avatar = ''; } - + await user.save(); - + done(null, user); } catch (err) { done(err); } - } + }, ); passport.use('openid', openidLogin); diff --git a/api/strategies/validators.js b/api/strategies/validators.js index db66c44ff3..7905007838 100644 --- a/api/strategies/validators.js +++ b/api/strategies/validators.js @@ -2,7 +2,7 @@ const Joi = require('joi'); const loginSchema = Joi.object().keys({ email: Joi.string().trim().email().required(), - password: Joi.string().trim().min(8).max(128).required() + password: Joi.string().trim().min(8).max(128).required(), }); const registerSchema = Joi.object().keys({ @@ -15,10 +15,10 @@ const registerSchema = Joi.object().keys({ .required(), email: Joi.string().trim().email().required(), password: Joi.string().trim().min(8).max(128).required(), - confirm_password: Joi.string().trim().min(8).max(128).required() + confirm_password: Joi.string().trim().min(8).max(128).required(), }); module.exports = { loginSchema, - registerSchema + registerSchema, }; diff --git a/api/utils/LoggingSystem.js b/api/utils/LoggingSystem.js index 3c536c150f..fdb7285133 100644 --- a/api/utils/LoggingSystem.js +++ b/api/utils/LoggingSystem.js @@ -13,10 +13,10 @@ const logger = pino({ 'env.JWT_SECRET', 'env.JWT_SECRET_DEV', 'env.JWT_SECRET_PROD', - 'newUser.password' + 'newUser.password', ], // See example to filter object class instances - censor: '***' // Redaction character - } + censor: '***', // Redaction character + }, }); // Sanitize outside the logger paths. This is useful for sanitizing variables directly with Regex and patterns. @@ -33,7 +33,7 @@ const redactPatterns = [ /authorization[-_]?login[-_]?hint/i, /authorization[-_]?acr[-_]?values/i, /authorization[-_]?response[-_]?mode/i, - /authorization[-_]?nonce/i + /authorization[-_]?nonce/i, ]; /* @@ -58,7 +58,7 @@ const levels = { INFO: 30, WARN: 40, ERROR: 50, - FATAL: 60 + FATAL: 60, }; let level = levels.INFO; @@ -121,6 +121,6 @@ module.exports = { if (level < levels.DEBUG) return next(); logger.debug({ query: req.query, body: req.body }, `Hit URL ${req.url} with following`); return next(); - } - } + }, + }, }; diff --git a/api/utils/abortMessage.js b/api/utils/abortMessage.js index fea2e7d31a..24c56479eb 100644 --- a/api/utils/abortMessage.js +++ b/api/utils/abortMessage.js @@ -1,6 +1,6 @@ async function abortMessage(req, res, abortControllers) { const { abortKey } = req.body; - console.log(`req.body`, req.body); + console.log('req.body', req.body); if (!abortControllers.has(abortKey)) { return res.status(404).send('Request not found'); } diff --git a/api/utils/azureUtils.js b/api/utils/azureUtils.js index 825a9feba8..6330e6080c 100644 --- a/api/utils/azureUtils.js +++ b/api/utils/azureUtils.js @@ -5,7 +5,7 @@ const genAzureEndpoint = ({ azureOpenAIApiInstanceName, azureOpenAIApiDeployment const genAzureChatCompletion = ({ azureOpenAIApiInstanceName, azureOpenAIApiDeploymentName, - azureOpenAIApiVersion + azureOpenAIApiVersion, }) => { return `https://${azureOpenAIApiInstanceName}.openai.azure.com/openai/deployments/${azureOpenAIApiDeploymentName}/chat/completions?api-version=${azureOpenAIApiVersion}`; } @@ -15,7 +15,7 @@ const getAzureCredentials = () => { azureOpenAIApiKey: process.env.AZURE_API_KEY ?? process.env.AZURE_OPENAI_API_KEY, azureOpenAIApiInstanceName: process.env.AZURE_OPENAI_API_INSTANCE_NAME, azureOpenAIApiDeploymentName: process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME, - azureOpenAIApiVersion: process.env.AZURE_OPENAI_API_VERSION + azureOpenAIApiVersion: process.env.AZURE_OPENAI_API_VERSION, } } diff --git a/api/utils/debug.js b/api/utils/debug.js index 71c45d8770..579d2c1129 100644 --- a/api/utils/debug.js +++ b/api/utils/debug.js @@ -2,7 +2,7 @@ const levels = { NONE: 0, LOW: 1, MEDIUM: 2, - HIGH: 3 + HIGH: 3, }; let level = levels.HIGH; @@ -41,6 +41,6 @@ module.exports = { console.log('Body:', req.body); console.groupEnd(); return next(); - } - } + }, + }, }; diff --git a/api/utils/index.js b/api/utils/index.js index 948a5f6ced..6a7ff501d7 100644 --- a/api/utils/index.js +++ b/api/utils/index.js @@ -10,5 +10,5 @@ module.exports = { maxTokensMap, tiktokenModels, sendEmail, - abortMessage + abortMessage, } \ No newline at end of file diff --git a/api/utils/sendEmail.js b/api/utils/sendEmail.js index 720137fec6..cb9b3d0ff2 100644 --- a/api/utils/sendEmail.js +++ b/api/utils/sendEmail.js @@ -13,8 +13,8 @@ const sendEmail = async (email, subject, payload, template) => { port: 465, auth: { user: process.env.EMAIL_USERNAME, - pass: process.env.EMAIL_PASSWORD - } + pass: process.env.EMAIL_PASSWORD, + }, }); const source = fs.readFileSync(path.join(__dirname, template), 'utf8'); @@ -24,7 +24,7 @@ const sendEmail = async (email, subject, payload, template) => { from: process.env.FROM_EMAIL, to: email, subject: subject, - html: compiledTemplate(payload) + html: compiledTemplate(payload), }; }; @@ -34,7 +34,7 @@ const sendEmail = async (email, subject, payload, template) => { return error; } else { return res.status(200).json({ - success: true + success: true, }); } }); diff --git a/api/utils/tokens.js b/api/utils/tokens.js index 39d1b182c9..7d0cb02377 100644 --- a/api/utils/tokens.js +++ b/api/utils/tokens.js @@ -34,7 +34,7 @@ const models = [ 'gpt-4-32k', 'gpt-4-32k-0314', 'gpt-3.5-turbo', - 'gpt-3.5-turbo-0301' + 'gpt-3.5-turbo-0301', ]; const maxTokensMap = { diff --git a/client/src/App.jsx b/client/src/App.jsx index 6840a209d0..e3f8cd5b22 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -16,8 +16,8 @@ const App = () => { if (error?.response?.status === 401) { setError(error); } - } - }) + }, + }), }); return ( diff --git a/client/src/components/Auth/LoginForm.tsx b/client/src/components/Auth/LoginForm.tsx index b74d927927..71ad3e9d8b 100644 --- a/client/src/components/Auth/LoginForm.tsx +++ b/client/src/components/Auth/LoginForm.tsx @@ -14,7 +14,7 @@ function LoginForm({ onSubmit }: TLoginFormProps) { const { register, handleSubmit, - formState: { errors } + formState: { errors }, } = useForm(); return ( @@ -35,16 +35,16 @@ function LoginForm({ onSubmit }: TLoginFormProps) { required: localize(lang, 'com_auth_email_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_email_min_length') + message: localize(lang, 'com_auth_email_min_length'), }, maxLength: { value: 120, - message: localize(lang, 'com_auth_email_max_length') + message: localize(lang, 'com_auth_email_max_length'), }, pattern: { value: /\S+@\S+\.\S+/, - message: localize(lang, 'com_auth_email_pattern') - } + message: localize(lang, 'com_auth_email_pattern'), + }, })} aria-invalid={!!errors.email} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -75,12 +75,12 @@ function LoginForm({ onSubmit }: TLoginFormProps) { required: localize(lang, 'com_auth_password_required'), minLength: { value: 8, - message: localize(lang, 'com_auth_password_min_length') + message: localize(lang, 'com_auth_password_min_length'), }, maxLength: { value: 40, - message: localize(lang, 'com_auth_password_max_length') - } + message: localize(lang, 'com_auth_password_max_length'), + }, })} aria-invalid={!!errors.password} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" diff --git a/client/src/components/Auth/Registration.tsx b/client/src/components/Auth/Registration.tsx index 3ee0dfe818..296f7fc866 100644 --- a/client/src/components/Auth/Registration.tsx +++ b/client/src/components/Auth/Registration.tsx @@ -7,7 +7,7 @@ import { localize } from '~/localization/Translation'; import { useRegisterUserMutation, TRegisterUser, - useGetStartupConfig + useGetStartupConfig, } from '@librechat/data-provider'; import { GoogleIcon, OpenIDIcon, GithubIcon, DiscordIcon } from '~/components' @@ -21,7 +21,7 @@ function Registration() { register, watch, handleSubmit, - formState: { errors } + formState: { errors }, } = useForm({ mode: 'onChange' }); const [error, setError] = useState(false); @@ -42,7 +42,7 @@ function Registration() { //@ts-ignore - error is of type unknown setErrorMessage(error.response?.data?.message); } - } + }, }); }; @@ -81,12 +81,12 @@ function Registration() { required: localize(lang, 'com_auth_name_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_name_min_length') + message: localize(lang, 'com_auth_name_min_length'), }, maxLength: { value: 80, - message: localize(lang, 'com_auth_name_max_length') - } + message: localize(lang, 'com_auth_name_max_length'), + }, })} aria-invalid={!!errors.name} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -117,12 +117,12 @@ function Registration() { required: localize(lang, 'com_auth_username_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_username_min_length') + message: localize(lang, 'com_auth_username_min_length'), }, maxLength: { value: 20, - message: localize(lang, 'com_auth_username_max_length') - } + message: localize(lang, 'com_auth_username_max_length'), + }, })} aria-invalid={!!errors.username} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -155,16 +155,16 @@ function Registration() { required: localize(lang, 'com_auth_email_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_email_min_length') + message: localize(lang, 'com_auth_email_min_length'), }, maxLength: { value: 120, - message: localize(lang, 'com_auth_email_max_length') + message: localize(lang, 'com_auth_email_max_length'), }, pattern: { value: /\S+@\S+\.\S+/, - message: localize(lang, 'com_auth_email_pattern') - } + message: localize(lang, 'com_auth_email_pattern'), + }, })} aria-invalid={!!errors.email} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -196,12 +196,12 @@ function Registration() { required: localize(lang, 'com_auth_password_required'), minLength: { value: 8, - message: localize(lang, 'com_auth_password_min_length') + message: localize(lang, 'com_auth_password_min_length'), }, maxLength: { value: 128, - message: localize(lang, 'com_auth_password_max_length') - } + message: localize(lang, 'com_auth_password_max_length'), + }, })} aria-invalid={!!errors.password} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -235,7 +235,7 @@ function Registration() { // return false; // }} {...register('confirm_password', { - validate: (value) => value === password || localize(lang, 'com_auth_password_not_match') + validate: (value) => value === password || localize(lang, 'com_auth_password_not_match'), })} aria-invalid={!!errors.confirm_password} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" diff --git a/client/src/components/Auth/RequestPasswordReset.tsx b/client/src/components/Auth/RequestPasswordReset.tsx index 14756d6b5b..fad71e8edb 100644 --- a/client/src/components/Auth/RequestPasswordReset.tsx +++ b/client/src/components/Auth/RequestPasswordReset.tsx @@ -6,7 +6,7 @@ import { localize } from '~/localization/Translation'; import { useRequestPasswordResetMutation, TRequestPasswordReset, - TRequestPasswordResetResponse + TRequestPasswordResetResponse, } from '@librechat/data-provider'; function RequestPasswordReset() { @@ -14,7 +14,7 @@ function RequestPasswordReset() { const { register, handleSubmit, - formState: { errors } + formState: { errors }, } = useForm(); const requestPasswordReset = useRequestPasswordResetMutation(); const [success, setSuccess] = useState(false); @@ -32,7 +32,7 @@ function RequestPasswordReset() { setTimeout(() => { setRequestError(false); }, 5000); - } + }, }); }; @@ -78,16 +78,16 @@ function RequestPasswordReset() { required: localize(lang, 'com_auth_email_required'), minLength: { value: 3, - message: localize(lang, 'com_auth_email_min_length') + message: localize(lang, 'com_auth_email_min_length'), }, maxLength: { value: 120, - message: localize(lang, 'com_auth_email_max_length') + message: localize(lang, 'com_auth_email_max_length'), }, pattern: { value: /\S+@\S+\.\S+/, - message: localize(lang, 'com_auth_email_pattern') - } + message: localize(lang, 'com_auth_email_pattern'), + }, })} aria-invalid={!!errors.email} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" diff --git a/client/src/components/Auth/ResetPassword.tsx b/client/src/components/Auth/ResetPassword.tsx index e885c76e49..6043a31998 100644 --- a/client/src/components/Auth/ResetPassword.tsx +++ b/client/src/components/Auth/ResetPassword.tsx @@ -12,7 +12,7 @@ function ResetPassword() { register, handleSubmit, watch, - formState: { errors } + formState: { errors }, } = useForm(); const resetPassword = useResetPasswordMutation(); const [resetError, setResetError] = useState(false); @@ -24,7 +24,7 @@ function ResetPassword() { resetPassword.mutate(data, { onError: () => { setResetError(true); - } + }, }); }; @@ -97,12 +97,12 @@ function ResetPassword() { required: localize(lang, 'com_auth_password_required'), minLength: { value: 8, - message: localize(lang, 'com_auth_password_min_length') + message: localize(lang, 'com_auth_password_min_length'), }, maxLength: { value: 128, - message: localize(lang, 'com_auth_password_max_length') - } + message: localize(lang, 'com_auth_password_max_length'), + }, })} aria-invalid={!!errors.password} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" @@ -135,7 +135,7 @@ function ResetPassword() { return false; }} {...register('confirm_password', { - validate: (value) => value === password || localize(lang, 'com_auth_password_not_match') + validate: (value) => value === password || localize(lang, 'com_auth_password_not_match'), })} aria-invalid={!!errors.confirm_password} className="peer block w-full appearance-none rounded-t-md border-0 border-b-2 border-gray-300 bg-gray-50 px-2.5 pb-2.5 pt-5 text-sm text-gray-900 focus:border-green-500 focus:outline-none focus:ring-0" diff --git a/client/src/components/Auth/__tests__/Login.spec.tsx b/client/src/components/Auth/__tests__/Login.spec.tsx index b142367546..73f35648c7 100644 --- a/client/src/components/Auth/__tests__/Login.spec.tsx +++ b/client/src/components/Auth/__tests__/Login.spec.tsx @@ -9,14 +9,14 @@ const setup = ({ useGetUserQueryReturnValue = { isLoading: false, isError: false, - data: {} + data: {}, }, useLoginUserReturnValue = { isLoading: false, isError: false, mutate: jest.fn(), data: {}, - isSuccess: false + isSuccess: false, }, useGetStartupCongfigReturnValue = { isLoading: false, @@ -30,9 +30,9 @@ const setup = ({ discordLoginEnabled: true, registrationEnabled: true, socialLoginEnabled: true, - serverDomain: 'mock-server' - } - } + serverDomain: 'mock-server', + }, + }, } = {}) => { const mockUseLoginUser = jest .spyOn(mockDataProvider, 'useLoginUserMutation') @@ -51,7 +51,7 @@ const setup = ({ ...renderResult, mockUseLoginUser, mockUseGetUserQuery, - mockUseGetStartupConfig + mockUseGetStartupConfig, }; }; @@ -65,7 +65,7 @@ test('renders login form', () => { expect(getByRole('link', { name: /Login with Google/i })).toBeInTheDocument(); expect(getByRole('link', { name: /Login with Google/i })).toHaveAttribute( 'href', - 'mock-server/oauth/google' + 'mock-server/oauth/google', ); }); @@ -76,8 +76,8 @@ test('calls loginUser.mutate on login', async () => { useLoginUserReturnValue: { isLoading: false, mutate: mutate, - isError: false - } + isError: false, + }, }); const emailInput = getByLabelText(/email/i); @@ -98,8 +98,8 @@ test('Navigates to / on successful login', async () => { isLoading: false, mutate: jest.fn(), isError: false, - isSuccess: true - } + isSuccess: true, + }, }); const emailInput = getByLabelText(/email/i); diff --git a/client/src/components/Auth/__tests__/Registration.spec.tsx b/client/src/components/Auth/__tests__/Registration.spec.tsx index f0bc8fa51f..66bcfc3527 100644 --- a/client/src/components/Auth/__tests__/Registration.spec.tsx +++ b/client/src/components/Auth/__tests__/Registration.spec.tsx @@ -9,14 +9,14 @@ const setup = ({ useGetUserQueryReturnValue = { isLoading: false, isError: false, - data: {} + data: {}, }, useRegisterUserMutationReturnValue = { isLoading: false, isError: false, mutate: jest.fn(), data: {}, - isSuccess: false + isSuccess: false, }, useGetStartupCongfigReturnValue = { isLoading: false, @@ -30,9 +30,9 @@ const setup = ({ discordLoginEnabled: true, registrationEnabled: true, socialLoginEnabled: true, - serverDomain: 'mock-server' - } - } + serverDomain: 'mock-server', + }, + }, } = {}) => { const mockUseRegisterUserMutation = jest .spyOn(mockDataProvider, 'useRegisterUserMutation') @@ -53,7 +53,7 @@ const setup = ({ ...renderResult, mockUseRegisterUserMutation, mockUseGetUserQuery, - mockUseGetStartupConfig + mockUseGetStartupConfig, }; }; @@ -72,7 +72,7 @@ test('renders registration form', () => { expect(getByRole('link', { name: /Login with Google/i })).toBeInTheDocument(); expect(getByRole('link', { name: /Login with Google/i })).toHaveAttribute( 'href', - 'mock-server/oauth/google' + 'mock-server/oauth/google', ); }); @@ -84,8 +84,8 @@ test('calls registerUser.mutate on registration', async () => { isLoading: false, mutate: mutate, isError: false, - isSuccess: true - } + isSuccess: true, + }, }); await userEvent.type(getByRole('textbox', { name: /Full name/i }), 'John Doe'); @@ -126,8 +126,8 @@ test('shows error message when registration fails', async () => { mutate: mutate, error: new Error('Registration failed'), data: {}, - isSuccess: false - } + isSuccess: false, + }, }); await userEvent.type(getByRole('textbox', { name: /Full name/i }), 'John Doe'); @@ -140,7 +140,7 @@ test('shows error message when registration fails', async () => { waitFor(() => { expect(screen.getByRole('alert')).toBeInTheDocument(); expect(screen.getByRole('alert')).toHaveTextContent( - /There was an error attempting to register your account. Please try again. Registration failed/i + /There was an error attempting to register your account. Please try again. Registration failed/i, ); }); }); diff --git a/client/src/components/Conversations/Conversation.jsx b/client/src/components/Conversations/Conversation.jsx index 9c2503e30a..5ed04e958e 100644 --- a/client/src/components/Conversations/Conversation.jsx +++ b/client/src/components/Conversations/Conversation.jsx @@ -72,7 +72,7 @@ export default function Conversation({ conversation, retainView }) { if (conversationId == currentConversation?.conversationId) { setCurrentConversation((prevState) => ({ ...prevState, - title: titleInput + title: titleInput, })); } } @@ -87,7 +87,7 @@ export default function Conversation({ conversation, retainView }) { const aProps = { className: - 'animate-flash group relative flex cursor-pointer items-center gap-3 break-all rounded-md bg-gray-800 py-3 px-3 pr-14 hover:bg-gray-800' + 'animate-flash group relative flex cursor-pointer items-center gap-3 break-all rounded-md bg-gray-800 py-3 px-3 pr-14 hover:bg-gray-800', }; if (currentConversation?.conversationId !== conversationId) { diff --git a/client/src/components/Endpoints/Anthropic/OptionHover.jsx b/client/src/components/Endpoints/Anthropic/OptionHover.jsx index 6193742e2b..0e8a3c5fd8 100644 --- a/client/src/components/Endpoints/Anthropic/OptionHover.jsx +++ b/client/src/components/Endpoints/Anthropic/OptionHover.jsx @@ -4,9 +4,9 @@ import { HoverCardPortal, HoverCardContent } from '~/components/ui/HoverCard.tsx const types = { temp: 'Ranges from 0 to 1. Use temp closer to 0 for analytical / multiple choice, and closer to 1 for creative and generative tasks. We recommend altering this or Top P but not both.', topp: 'Top-p changes how the model selects tokens for output. Tokens are selected from most K (see topK parameter) probable to least until the sum of their probabilities equals the top-p value.', - topk: "Top-k changes how the model selects tokens for output. A top-k of 1 means the selected token is the most probable among all tokens in the model's vocabulary (also called greedy decoding), while a top-k of 3 means that the next token is selected from among the 3 most probable tokens (using temperature).", + topk: 'Top-k changes how the model selects tokens for output. A top-k of 1 means the selected token is the most probable among all tokens in the model\'s vocabulary (also called greedy decoding), while a top-k of 3 means that the next token is selected from among the 3 most probable tokens (using temperature).', maxoutputtokens: - ' Maximum number of tokens that can be generated in the response. Specify a lower value for shorter responses and a higher value for longer responses.' + ' Maximum number of tokens that can be generated in the response. Specify a lower value for shorter responses and a higher value for longer responses.', }; function OptionHover({ type, side }) { diff --git a/client/src/components/Endpoints/Anthropic/Settings.jsx b/client/src/components/Endpoints/Anthropic/Settings.jsx index 2b40dfa412..8bb71f7499 100644 --- a/client/src/components/Endpoints/Anthropic/Settings.jsx +++ b/client/src/components/Endpoints/Anthropic/Settings.jsx @@ -27,7 +27,7 @@ function Settings(props) { topP, topK, maxOutputTokens, - setOption + setOption, } = props; const endpointsConfig = useRecoilValue(store.endpointsConfig); @@ -43,7 +43,7 @@ function Settings(props) { const models = endpointsConfig?.['anthropic']?.['availableModels'] || []; return ( -
+
@@ -54,7 +54,7 @@ function Settings(props) { disabled={readonly} className={cn( defaultTextProps, - 'z-50 flex w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0' + 'z-50 flex w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0', )} containerClassName="flex w-full resize-none" /> @@ -71,7 +71,7 @@ function Settings(props) { placeholder="Set a custom name for Claude" className={cn( defaultTextProps, - 'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0' + 'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0', )} />
@@ -87,7 +87,7 @@ function Settings(props) { placeholder="Set custom instructions or context. Ignored if empty." className={cn( defaultTextProps, - 'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2 ' + 'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2 ', )} />
@@ -112,8 +112,8 @@ function Settings(props) { defaultTextProps, cn( optionText, - 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200' - ) + 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200', + ), )} />
@@ -149,8 +149,8 @@ function Settings(props) { defaultTextProps, cn( optionText, - 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200' - ) + 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200', + ), )} />
@@ -187,8 +187,8 @@ function Settings(props) { defaultTextProps, cn( optionText, - 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200' - ) + 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200', + ), )} />
@@ -224,8 +224,8 @@ function Settings(props) { defaultTextProps, cn( optionText, - 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200' - ) + 'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200', + ), )} /> diff --git a/client/src/components/Endpoints/BingAI/Settings.jsx b/client/src/components/Endpoints/BingAI/Settings.jsx index 65438edb04..fc6e65c507 100644 --- a/client/src/components/Endpoints/BingAI/Settings.jsx +++ b/client/src/components/Endpoints/BingAI/Settings.jsx @@ -33,8 +33,8 @@ function Settings(props) { { onSuccess: (data) => { setTokenCount(data.count); - } - } + }, + }, ); }; @@ -59,7 +59,7 @@ function Settings(props) { disabled={readonly} className={cn( defaultTextProps, - 'flex w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0' + 'flex w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0', )} containerClassName="flex w-full resize-none" /> @@ -76,7 +76,7 @@ function Settings(props) { placeholder="Bing can use up to 7k tokens for 'context', which it can reference for the conversation. The specific limit is not known but may run into errors exceeding 7k tokens" className={cn( defaultTextProps, - 'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2' + 'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2', )} /> {`Token count: ${tokenCount}`} @@ -129,7 +129,7 @@ function Settings(props) { placeholder="WARNING: Misuse of this feature can get you BANNED from using Bing! Click on 'System Message' for full instructions and the default message if omitted, which is the 'Sydney' preset that is considered safe." className={cn( defaultTextProps, - 'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2 placeholder:text-red-400' + 'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2 placeholder:text-red-400', )} /> diff --git a/client/src/components/Endpoints/EditPresetDialog.jsx b/client/src/components/Endpoints/EditPresetDialog.jsx index d13e9ace5f..338d5dd73c 100644 --- a/client/src/components/Endpoints/EditPresetDialog.jsx +++ b/client/src/components/Endpoints/EditPresetDialog.jsx @@ -16,7 +16,7 @@ import { Dialog, DialogClose, DialogButton, - DialogTemplate + DialogTemplate, } from '~/components/'; import { cn } from '~/utils/'; import cleanupPreset from '~/utils/cleanupPreset'; @@ -42,10 +42,10 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { cleanupPreset({ preset: { ...prevState, - ...update + ...update, }, - endpointsConfig - }) + endpointsConfig, + }), ); }; @@ -58,10 +58,10 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { cleanupPreset({ preset: { ...prevState, - agentOptions + agentOptions, }, - endpointsConfig - }) + endpointsConfig, + }), ); }; @@ -76,10 +76,10 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { cleanupPreset({ preset: { ...prevState, - ...update + ...update, }, - endpointsConfig - }) + endpointsConfig, + }), ); }; @@ -92,10 +92,10 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { cleanupPreset({ preset: { ...prevState, - ...update + ...update, }, - endpointsConfig - }) + endpointsConfig, + }), ); }; @@ -108,10 +108,10 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { cleanupPreset({ preset: { ...prevState, - ...update + ...update, }, - endpointsConfig - }) + endpointsConfig, + }), ); return; } @@ -121,10 +121,10 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { cleanupPreset({ preset: { ...prevState, - ...update + ...update, }, - endpointsConfig - }) + endpointsConfig, + }), ); }; @@ -136,7 +136,7 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { method: 'post', url: '/api/presets', data: cleanupPreset({ preset, endpointsConfig }), - withCredentials: true + withCredentials: true, }).then((res) => { setPresets(res?.data); }); @@ -147,7 +147,7 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { exportFromJSON({ data: cleanupPreset({ preset, endpointsConfig }), fileName, - exportType: exportFromJSON.types.json + exportType: exportFromJSON.types.json, }); }; @@ -183,7 +183,7 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { placeholder="Set a custom name, in case you can find this preset" className={cn( defaultTextProps, - 'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0' + 'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0', )} /> @@ -198,7 +198,7 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { options={availableEndpoints} className={cn( defaultTextProps, - 'flex h-10 max-h-10 w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0' + 'flex h-10 max-h-10 w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0', )} containerClassName="flex w-full resize-none" /> diff --git a/client/src/components/Endpoints/EndpointOptionsDialog.jsx b/client/src/components/Endpoints/EndpointOptionsDialog.jsx index 003b99af87..85e4e47030 100644 --- a/client/src/components/Endpoints/EndpointOptionsDialog.jsx +++ b/client/src/components/Endpoints/EndpointOptionsDialog.jsx @@ -21,7 +21,7 @@ const EndpointOptionsDialog = ({ open, onOpenChange, preset: _preset, title }) = update[param] = newValue; setPreset((prevState) => ({ ...prevState, - ...update + ...update, })); }; @@ -33,7 +33,7 @@ const EndpointOptionsDialog = ({ open, onOpenChange, preset: _preset, title }) = exportFromJSON({ data: cleanupPreset({ preset, endpointsConfig }), fileName: `${preset?.title}.json`, - exportType: exportFromJSON.types.json + exportType: exportFromJSON.types.json, }); }; diff --git a/client/src/components/Endpoints/EndpointOptionsPopover.jsx b/client/src/components/Endpoints/EndpointOptionsPopover.jsx index cf0ad66c04..dbab55656e 100644 --- a/client/src/components/Endpoints/EndpointOptionsPopover.jsx +++ b/client/src/components/Endpoints/EndpointOptionsPopover.jsx @@ -10,7 +10,7 @@ function EndpointOptionsPopover({ visible, saveAsPreset, switchToSimpleMode, - additionalButton = null + additionalButton = null, }) { const cardStyle = 'shadow-md rounded-md min-w-[75px] font-normal bg-white border-black/10 border dark:bg-gray-700 text-black dark:text-white'; @@ -42,7 +42,7 @@ function EndpointOptionsPopover({ {additionalButton && ( @@ -175,7 +175,7 @@ function PluginsOptions() { className={cn( cardStyle, 'min-w-4 z-50 flex h-[40px] flex-none items-center justify-center px-4 hover:bg-slate-50 focus:ring-0 focus:ring-offset-0 dark:hover:bg-gray-600', - !visibile && 'hidden' + !visibile && 'hidden', )} onClick={triggerAdvancedMode} > @@ -220,7 +220,7 @@ function PluginsOptions() { additionalButton={{ label: `Show ${showAgentSettings ? 'Completion' : 'Agent'} Settings`, handler: triggerAgentSettings, - icon: + icon: , }} /> - ) + ), }; diff --git a/client/src/components/Input/SetTokenDialog/InputWithLabel.tsx b/client/src/components/Input/SetTokenDialog/InputWithLabel.tsx index fff1a6f3c0..fcaf4b6c9b 100644 --- a/client/src/components/Input/SetTokenDialog/InputWithLabel.tsx +++ b/client/src/components/Input/SetTokenDialog/InputWithLabel.tsx @@ -27,7 +27,7 @@ const InputWithLabel: FC = ({ value, onChange, label, id }) placeholder={`Enter ${label}`} className={cn( defaultTextProps, - 'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0' + 'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0', )} /> diff --git a/client/src/components/Input/SetTokenDialog/SetTokenDialog.tsx b/client/src/components/Input/SetTokenDialog/SetTokenDialog.tsx index 63954c69f9..ed9ffd1306 100644 --- a/client/src/components/Input/SetTokenDialog/SetTokenDialog.tsx +++ b/client/src/components/Input/SetTokenDialog/SetTokenDialog.tsx @@ -21,7 +21,7 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => { 'openAI': OpenAIConfig, 'azureOpenAI': OpenAIConfig, 'gptPlugins': OpenAIConfig, - 'default': OtherConfig + 'default': OtherConfig, }; const EndpointComponent = endpointComponents[endpoint] || endpointComponents['default']; @@ -42,7 +42,7 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => { selection={{ selectHandler: submit, selectClasses: 'bg-green-600 hover:bg-green-700 dark:hover:bg-green-800 text-white', - selectText: 'Submit' + selectText: 'Submit', }} /> diff --git a/client/src/components/Input/SubmitButton.jsx b/client/src/components/Input/SubmitButton.jsx index 44c892d64e..24e7e1b0e2 100644 --- a/client/src/components/Input/SubmitButton.jsx +++ b/client/src/components/Input/SubmitButton.jsx @@ -10,7 +10,7 @@ export default function SubmitButton({ handleStopGenerating, disabled, isSubmitting, - endpointsConfig + endpointsConfig, }) { const [setTokenDialogOpen, setSetTokenDialogOpen] = useState(false); const { getToken } = store.useToken(endpoint); diff --git a/client/src/components/MessageHandler/index.jsx b/client/src/components/MessageHandler/index.jsx index a3e04a0fc7..d284b646b4 100644 --- a/client/src/components/MessageHandler/index.jsx +++ b/client/src/components/MessageHandler/index.jsx @@ -26,9 +26,9 @@ export default function MessageHandler() { parentMessageId: message?.overrideParentMessageId, messageId: message?.overrideParentMessageId + '_', plugin: plugin ? plugin : null, - submitting: true + submitting: true, // unfinished: true - } + }, ]); } else { setMessages([ @@ -40,9 +40,9 @@ export default function MessageHandler() { parentMessageId: message?.messageId, messageId: message?.messageId + '_', plugin: plugin ? plugin : null, - submitting: true + submitting: true, // unfinished: true - } + }, ]); } }; @@ -74,7 +74,7 @@ export default function MessageHandler() { setConversation((prevState) => ({ ...prevState, - ...conversation + ...conversation, })); }; @@ -88,8 +88,8 @@ export default function MessageHandler() { ...initialResponse, parentMessageId: message?.overrideParentMessageId, messageId: message?.overrideParentMessageId + '_', - submitting: true - } + submitting: true, + }, ]); else setMessages([ @@ -99,14 +99,14 @@ export default function MessageHandler() { ...initialResponse, parentMessageId: message?.messageId, messageId: message?.messageId + '_', - submitting: true - } + submitting: true, + }, ]); const { conversationId } = message; setConversation((prevState) => ({ ...prevState, - conversationId + conversationId, })); resetLatestMessage(); }; @@ -138,7 +138,7 @@ export default function MessageHandler() { setConversation((prevState) => ({ ...prevState, - ...conversation + ...conversation, })); }; @@ -149,7 +149,7 @@ export default function MessageHandler() { const errorResponse = { ...data, error: true, - parentMessageId: message?.messageId + parentMessageId: message?.messageId, }; setIsSubmitting(false); setMessages([...messages, message, errorResponse]); @@ -164,11 +164,11 @@ export default function MessageHandler() { method: 'POST', headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${token}` + Authorization: `Bearer ${token}`, }, body: JSON.stringify({ - abortKey: conversationId - }) + abortKey: conversationId, + }), }) .then((response) => response.json()) .then((data) => { @@ -193,7 +193,7 @@ export default function MessageHandler() { const events = new SSE(server, { payload: JSON.stringify(payload), - headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` } + headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, }); events.onmessage = (e) => { @@ -206,7 +206,7 @@ export default function MessageHandler() { if (data.created) { message = { ...data.message, - overrideParentMessageId: message?.overrideParentMessageId + overrideParentMessageId: message?.overrideParentMessageId, }; createdHandler(data, { ...submission, message }); console.log('created', message); diff --git a/client/src/components/Messages/Content/Content.jsx b/client/src/components/Messages/Content/Content.jsx index a34438e016..dc5acd9338 100644 --- a/client/src/components/Messages/Content/Content.jsx +++ b/client/src/components/Messages/Content/Content.jsx @@ -62,10 +62,10 @@ const Content = React.memo(({ content, message }) => { { detect: true, ignoreMissing: true, - subset: langSubset - } + subset: langSubset, + }, ], - [rehypeRaw] + [rehypeRaw], ]; if (!isInitializing || !isLatestMessage) { @@ -79,7 +79,7 @@ const Content = React.memo(({ content, message }) => { linkTarget="_new" components={{ code, - p + p, }} > {isLatestMessage && isSubmitting && !isInitializing ? (content ?? '') + cursor : content} diff --git a/client/src/components/Messages/HoverButtons.jsx b/client/src/components/Messages/HoverButtons.jsx index ab2d06a155..dba6bbee00 100644 --- a/client/src/components/Messages/HoverButtons.jsx +++ b/client/src/components/Messages/HoverButtons.jsx @@ -12,7 +12,7 @@ export default function HoverButtons({ conversation, isSubmitting, message, - regenerate + regenerate, }) { const { endpoint } = conversation; const [isCopied, setIsCopied] = React.useState(false); @@ -20,7 +20,7 @@ export default function HoverButtons({ const branchingSupported = // azureOpenAI, openAI, chatGPTBrowser support branching, so edit enabled // 5/21/23: Bing is allowing editing and Message regenerating !!['azureOpenAI', 'openAI', 'chatGPTBrowser', 'google', 'bingAI', 'gptPlugins', 'anthropic'].find( - (e) => e === endpoint + (e) => e === endpoint, ); // Sydney in bingAI supports branching, so edit enabled @@ -68,7 +68,7 @@ export default function HoverButtons({ } leftButtons={} - selection={{ selectHandler: mockSelectHandler, selectText: "Select" }} + selection={{ selectHandler: mockSelectHandler, selectText: 'Select' }} /> - + , ); expect(getByText('Test Dialog')).toBeInTheDocument(); @@ -40,7 +40,7 @@ describe('DialogTemplate', () => { - + , ); expect(getByText('Test Dialog')).toBeInTheDocument(); @@ -57,9 +57,9 @@ describe('DialogTemplate', () => { {}}> - + , ); fireEvent.click(getByText('Select')); diff --git a/client/src/components/ui/DialogTemplate.tsx b/client/src/components/ui/DialogTemplate.tsx index 74669ec6ad..9778d66d2a 100644 --- a/client/src/components/ui/DialogTemplate.tsx +++ b/client/src/components/ui/DialogTemplate.tsx @@ -5,7 +5,7 @@ import { DialogDescription, DialogFooter, DialogHeader, - DialogTitle + DialogTitle, } from './'; import { cn } from '~/utils/'; diff --git a/client/src/components/ui/Dropdown.jsx b/client/src/components/ui/Dropdown.jsx index 9c7b1fdf5c..ed0cb9a02a 100644 --- a/client/src/components/ui/Dropdown.jsx +++ b/client/src/components/ui/Dropdown.jsx @@ -13,7 +13,7 @@ function Dropdown({ value, onChange, options, className, containerClassName }) { @@ -49,7 +49,7 @@ function Dropdown({ value, onChange, options, className, containerClassName }) { {item?.display ?? item} diff --git a/client/src/components/ui/DropdownMenu.tsx b/client/src/components/ui/DropdownMenu.tsx index 41e5bab68d..a74d97096b 100644 --- a/client/src/components/ui/DropdownMenu.tsx +++ b/client/src/components/ui/DropdownMenu.tsx @@ -29,7 +29,7 @@ const DropdownMenuSubTrigger = React.forwardRef< className={cn( 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm font-medium outline-none focus:bg-slate-100 data-[state=open]:bg-slate-100 dark:focus:bg-gray-900 dark:data-[state=open]:bg-gray-900', inset && 'pl-8', - className + className, )} {...props} > @@ -47,7 +47,7 @@ const DropdownMenuSubContent = React.forwardRef< ref={ref} className={cn( 'animate-in slide-in-from-left-1 z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400', - className + className, )} {...props} /> @@ -64,7 +64,7 @@ const DropdownMenuContent = React.forwardRef< sideOffset={sideOffset} className={cn( 'animate-in data-[side=right]:slide-in-from-left-2 data-[side=left]:slide-in-from-right-2 data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-100 bg-white p-1 text-slate-700 shadow-md dark:border-slate-800 dark:bg-slate-800 dark:text-slate-400', - className + className, )} {...props} /> @@ -83,7 +83,7 @@ const DropdownMenuItem = React.forwardRef< className={cn( 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-900', inset && 'pl-8', - className + className, )} {...props} /> @@ -98,7 +98,7 @@ const DropdownMenuCheckboxItem = React.forwardRef< ref={ref} className={cn( 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-900', - className + className, )} checked={checked} {...props} @@ -121,7 +121,7 @@ const DropdownMenuRadioItem = React.forwardRef< ref={ref} className={cn( className, - 'relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-800' + 'relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm font-medium outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-gray-800', )} {...props} > @@ -146,7 +146,7 @@ const DropdownMenuLabel = React.forwardRef< className={cn( 'px-2 py-1.5 text-sm font-semibold text-slate-900 dark:text-slate-300', inset && 'pl-8', - className + className, )} {...props} /> @@ -187,5 +187,5 @@ export { DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, - DropdownMenuRadioGroup + DropdownMenuRadioGroup, }; diff --git a/client/src/components/ui/HoverCard.tsx b/client/src/components/ui/HoverCard.tsx index 3695be90a3..b03b99f7b2 100644 --- a/client/src/components/ui/HoverCard.tsx +++ b/client/src/components/ui/HoverCard.tsx @@ -21,7 +21,7 @@ const HoverCardContent = React.forwardRef< sideOffset={sideOffset} className={cn( 'animate-in fade-in-0 z-50 w-64 rounded-md border border-gray-100 bg-white p-4 shadow-md outline-none dark:border-gray-800 dark:bg-gray-800', - className + className, )} {...props} /> diff --git a/client/src/components/ui/Input.tsx b/client/src/components/ui/Input.tsx index 37d21a63e8..ba2de12066 100644 --- a/client/src/components/ui/Input.tsx +++ b/client/src/components/ui/Input.tsx @@ -9,7 +9,7 @@ const Input = React.forwardRef(({ className, ...pr diff --git a/client/src/components/ui/ModelSelect.jsx b/client/src/components/ui/ModelSelect.jsx index e2ce430c4a..765197c676 100644 --- a/client/src/components/ui/ModelSelect.jsx +++ b/client/src/components/ui/ModelSelect.jsx @@ -7,7 +7,7 @@ import { DropdownMenuRadioGroup, DropdownMenuSeparator, DropdownMenuTrigger, - DropdownMenuRadioItem + DropdownMenuRadioItem, } from './DropdownMenu.tsx'; import store from '~/store'; import { useRecoilValue } from 'recoil'; diff --git a/client/src/components/ui/MultiSelectDropDown.jsx b/client/src/components/ui/MultiSelectDropDown.jsx index 0fcf7225d0..6148752ba3 100644 --- a/client/src/components/ui/MultiSelectDropDown.jsx +++ b/client/src/components/ui/MultiSelectDropDown.jsx @@ -16,7 +16,7 @@ function MultiSelectDropDown({ containerClassName, isSelected, className, - optionValueKey = 'value' + optionValueKey = 'value', }) { const [isOpen, setIsOpen] = useState(false); const menuRef = useRef(null); @@ -37,7 +37,7 @@ function MultiSelectDropDown({ setIsOpen((prev) => !prev)} @@ -57,7 +57,7 @@ function MultiSelectDropDown({ {!showLabel && title.length > 0 && ( @@ -148,7 +148,7 @@ function MultiSelectDropDown({ {option.name} diff --git a/client/src/components/ui/SelectDropDown.jsx b/client/src/components/ui/SelectDropDown.jsx index 7785605a10..b30a3b71c2 100644 --- a/client/src/components/ui/SelectDropDown.jsx +++ b/client/src/components/ui/SelectDropDown.jsx @@ -13,18 +13,18 @@ function SelectDropDown({ showLabel = true, containerClassName, subContainerClassName, - className + className, }) { return (
-
+
{({ open }) => ( <> {' '} @@ -41,7 +41,7 @@ function SelectDropDown({ {!showLabel && ( @@ -87,7 +87,7 @@ function SelectDropDown({ {option} diff --git a/client/src/components/ui/Slider.tsx b/client/src/components/ui/Slider.tsx index 59fe8a3a9d..a4fe37af76 100644 --- a/client/src/components/ui/Slider.tsx +++ b/client/src/components/ui/Slider.tsx @@ -26,7 +26,7 @@ const Slider = React.forwardRef, S className="block h-4 w-4 rounded-full border-2 border-gray-400 bg-white transition-colors focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 dark:border-gray-100 dark:bg-gray-400 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900" /> - ) + ), ); Slider.displayName = SliderPrimitive.Root.displayName; diff --git a/client/src/components/ui/Switch.tsx b/client/src/components/ui/Switch.tsx index d17041c78c..a3be6d4aed 100644 --- a/client/src/components/ui/Switch.tsx +++ b/client/src/components/ui/Switch.tsx @@ -1,5 +1,5 @@ -import * as React from "react" -import * as SwitchPrimitives from "@radix-ui/react-switch" +import * as React from 'react' +import * as SwitchPrimitives from '@radix-ui/react-switch' import { cn } from '../../utils'; @@ -9,19 +9,19 @@ const Switch = React.forwardRef< >(({ className, ...props }, ref) => ( )) Switch.displayName = SwitchPrimitives.Root.displayName - + export { Switch } \ No newline at end of file diff --git a/client/src/components/ui/Tabs.tsx b/client/src/components/ui/Tabs.tsx index 95d1fa3e33..db13fde848 100644 --- a/client/src/components/ui/Tabs.tsx +++ b/client/src/components/ui/Tabs.tsx @@ -15,7 +15,7 @@ const TabsList = React.forwardRef< ref={ref} className={cn( 'inline-flex items-center justify-center rounded-md bg-gray-100 p-1 dark:bg-gray-800', - className + className, )} {...props} /> @@ -29,7 +29,7 @@ const TabsTrigger = React.forwardRef< (undefi export const ApiErrorBoundaryProvider = ({ value, - children + children, }: { value?: ApiError; children: React.ReactNode; diff --git a/client/src/hooks/AuthContext.tsx b/client/src/hooks/AuthContext.tsx index 0ec496fe8a..6f45c868fe 100644 --- a/client/src/hooks/AuthContext.tsx +++ b/client/src/hooks/AuthContext.tsx @@ -5,7 +5,7 @@ import { ReactNode, useCallback, createContext, - useContext + useContext, } from 'react'; import { TUser, @@ -15,7 +15,7 @@ import { useLogoutUserMutation, useGetUserQuery, useRefreshTokenMutation, - TLoginUser + TLoginUser, } from '@librechat/data-provider'; import { useNavigate } from 'react-router-dom'; @@ -44,7 +44,7 @@ const AuthContext = createContext(undefined); const AuthContextProvider = ({ authConfig, - children + children, }: { authConfig: TAuthConfig; children: ReactNode; @@ -86,7 +86,7 @@ const AuthContextProvider = ({ navigate(redirect, { replace: true }); } }, - [navigate] + [navigate], ); const getCookieValue = (key: string) => { @@ -103,7 +103,7 @@ const AuthContextProvider = ({ onError: (error) => { doSetError((error as Error).message); navigate('/login', { replace: true }); - } + }, }); }; @@ -119,12 +119,12 @@ const AuthContextProvider = ({ token: undefined, isAuthenticated: false, user: undefined, - redirect: '/login' + redirect: '/login', }); }, onError: (error) => { doSetError((error as Error).message); - } + }, }); }; @@ -154,7 +154,7 @@ const AuthContextProvider = ({ userQuery.error, error, navigate, - setUserContext + setUserContext, ]); // const silentRefresh = useCallback(() => { @@ -183,10 +183,10 @@ const AuthContextProvider = ({ isAuthenticated, error, login, - logout + logout, }), // eslint-disable-next-line react-hooks/exhaustive-deps - [user, error, isAuthenticated, token] + [user, error, isAuthenticated, token], ); return {children}; diff --git a/client/src/hooks/useDocumentTitle.js b/client/src/hooks/useDocumentTitle.js index 85e813602c..fdca259cea 100644 --- a/client/src/hooks/useDocumentTitle.js +++ b/client/src/hooks/useDocumentTitle.js @@ -1,8 +1,9 @@ // useDocumentTitle.js -import { useRef, useEffect } from 'react'; +import { useEffect } from 'react'; -function useDocumentTitle(title, prevailOnUnmount = false) { - const defaultTitle = useRef(document.title); +// function useDocumentTitle(title, prevailOnUnmount = false) { +// const defaultTitle = useRef(document.title); +function useDocumentTitle(title) { useEffect(() => { document.title = title; diff --git a/client/src/main.jsx b/client/src/main.jsx index c3ba2ccf3a..17c3985a46 100644 --- a/client/src/main.jsx +++ b/client/src/main.jsx @@ -10,5 +10,5 @@ const root = createRoot(container); root.render( - + , ); diff --git a/client/src/routes/Chat.jsx b/client/src/routes/Chat.jsx index 0bdf031e46..d6cf77c2b4 100644 --- a/client/src/routes/Chat.jsx +++ b/client/src/routes/Chat.jsx @@ -11,7 +11,7 @@ import store from '~/store'; import { useGetMessagesByConvoId, useGetConversationByIdMutation, - useGetStartupConfig + useGetStartupConfig, } from '@librechat/data-provider'; export default function Chat() { @@ -70,7 +70,7 @@ export default function Chat() { navigate('/chat/new'); newConversation(); setShouldNavigate(true); - } + }, }); setMessages(null); } diff --git a/client/src/routes/Root.jsx b/client/src/routes/Root.jsx index a04403f835..83ab215803 100644 --- a/client/src/routes/Root.jsx +++ b/client/src/routes/Root.jsx @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react'; import { useGetEndpointsQuery, useGetPresetsQuery, - useGetSearchEnabledQuery + useGetSearchEnabledQuery, } from '@librechat/data-provider'; import MessageHandler from '../components/MessageHandler'; diff --git a/client/src/routes/index.jsx b/client/src/routes/index.jsx index d4b236f8aa..11f46a8b68 100644 --- a/client/src/routes/index.jsx +++ b/client/src/routes/index.jsx @@ -16,22 +16,22 @@ const AuthLayout = () => ( export const router = createBrowserRouter([ { path: 'register', - element: + element: , }, { path: 'forgot-password', - element: + element: , }, { path: 'reset-password', - element: + element: , }, { element: , children: [ { path: 'login', - element: + element: , }, { path: '/', @@ -39,18 +39,18 @@ export const router = createBrowserRouter([ children: [ { index: true, - element: + element: , }, { path: 'chat/:conversationId?', - element: + element: , }, { path: 'search/:query?', - element: - } - ] - } - ] - } + element: , + }, + ], + }, + ], + }, ]); \ No newline at end of file diff --git a/client/src/store/conversation.js b/client/src/store/conversation.js index 0b955a4682..3c99487eb0 100644 --- a/client/src/store/conversation.js +++ b/client/src/store/conversation.js @@ -6,7 +6,7 @@ import { atomFamily, useSetRecoilState, useResetRecoilState, - useRecoilCallback + useRecoilCallback, } from 'recoil'; import buildTree from '~/utils/buildTree'; import getDefaultConversation from '~/utils/getDefaultConversation'; @@ -14,7 +14,7 @@ import submission from './submission.js'; const conversation = atom({ key: 'conversation', - default: null + default: null, }); // current messages of the conversation, must be an array @@ -22,24 +22,24 @@ const conversation = atom({ // [{text, sender, messageId, parentMessageId, isCreatedByUser}] const messages = atom({ key: 'messages', - default: [] + default: [], }); const messagesTree = selector({ key: 'messagesTree', get: ({ get }) => { return buildTree(get(messages), false); - } + }, }); const latestMessage = atom({ key: 'latestMessage', - default: null + default: null, }); const messagesSiblingIdxFamily = atomFamily({ key: 'messagesSiblingIdx', - default: 0 + default: 0, }); const useConversation = () => { @@ -52,7 +52,7 @@ const useConversation = () => { conversation, messages = null, preset = null, - { endpointsConfig = {}, prevConversation = {} } + { endpointsConfig = {}, prevConversation = {} }, ) => { let { endpoint = null } = conversation; @@ -62,7 +62,7 @@ const useConversation = () => { conversation, endpointsConfig, prevConversation, - preset + preset, }); setConversation(conversation); @@ -78,10 +78,10 @@ const useConversation = () => { const endpointsConfig = await snapshot.getPromise(endpoints.endpointsConfig); _switchToConversation(_conversation, messages, preset, { endpointsConfig, - prevConversation + prevConversation, }); }, - [] + [], ); const newConversation = useCallback((template = {}, preset) => { @@ -89,10 +89,10 @@ const useConversation = () => { { conversationId: 'new', title: 'New Chat', - ...template + ...template, }, [], - preset + preset, ); }, [switchToConversation]); @@ -100,9 +100,9 @@ const useConversation = () => { switchToConversation( { conversationId: 'search', - title: 'Search' + title: 'Search', }, - [] + [], ); }; @@ -115,5 +115,5 @@ export default { messagesTree, latestMessage, messagesSiblingIdxFamily, - useConversation + useConversation, }; diff --git a/client/src/store/conversations.js b/client/src/store/conversations.js index 8455f09871..b32a5b5e1e 100644 --- a/client/src/store/conversations.js +++ b/client/src/store/conversations.js @@ -3,7 +3,7 @@ import { useCallback } from 'react'; const refreshConversationsHint = atom({ key: 'refreshConversationsHint', - default: 1 + default: 1, }); const useConversations = () => { diff --git a/client/src/store/endpoints.js b/client/src/store/endpoints.js index 0ec70afbbc..78e41d3a94 100644 --- a/client/src/store/endpoints.js +++ b/client/src/store/endpoints.js @@ -9,8 +9,8 @@ const endpointsConfig = atom({ chatGPTBrowser: null, gptPlugins: null, google: null, - anthropic: null - } + anthropic: null, + }, }); const endpointsFilter = selector({ @@ -21,7 +21,7 @@ const endpointsFilter = selector({ let filter = {}; for (const key of Object.keys(config)) filter[key] = !!config[key]; return filter; - } + }, }); const availableEndpoints = selector({ @@ -30,12 +30,12 @@ const availableEndpoints = selector({ const endpoints = ['azureOpenAI', 'openAI', 'chatGPTBrowser', 'gptPlugins', 'bingAI', 'google', 'anthropic']; const f = get(endpointsFilter); return endpoints.filter((endpoint) => f[endpoint]); - } + }, }); // const modelAvailable export default { endpointsConfig, endpointsFilter, - availableEndpoints + availableEndpoints, }; diff --git a/client/src/store/index.js b/client/src/store/index.js index 19b15ac8d8..eb831783e9 100644 --- a/client/src/store/index.js +++ b/client/src/store/index.js @@ -19,5 +19,5 @@ export default { ...search, ...preset, ...token, - ...lang + ...lang, }; diff --git a/client/src/store/language.js b/client/src/store/language.js index ebd9d0b052..18e61a38fe 100644 --- a/client/src/store/language.js +++ b/client/src/store/language.js @@ -2,7 +2,7 @@ import { atom } from 'recoil'; const lang = atom({ key: 'lang', - default: 'en' + default: 'en', }); export default { lang }; diff --git a/client/src/store/preset.js b/client/src/store/preset.js index 0d4c4441fe..174e204c12 100644 --- a/client/src/store/preset.js +++ b/client/src/store/preset.js @@ -7,9 +7,9 @@ import { atom } from 'recoil'; // [preset1, preset2, preset3] const presets = atom({ key: 'presets', - default: [] + default: [], }); export default { - presets + presets, }; diff --git a/client/src/store/search.js b/client/src/store/search.js index ebc956def5..ba50a3f7a4 100644 --- a/client/src/store/search.js +++ b/client/src/store/search.js @@ -3,24 +3,24 @@ import buildTree from '~/utils/buildTree'; const isSearchEnabled = atom({ key: 'isSearchEnabled', - default: null + default: null, }); const searchQuery = atom({ key: 'searchQuery', - default: '' + default: '', }); const searchResultMessages = atom({ key: 'searchResultMessages', - default: null + default: null, }); const searchResultMessagesTree = selector({ key: 'searchResultMessagesTree', get: ({ get }) => { return buildTree(get(searchResultMessages), true); - } + }, }); const isSearching = selector({ @@ -28,7 +28,7 @@ const isSearching = selector({ get: ({ get }) => { const data = get(searchQuery); return !!data; - } + }, }); export default { @@ -36,5 +36,5 @@ export default { isSearching, searchResultMessages, searchResultMessagesTree, - searchQuery + searchQuery, }; diff --git a/client/src/store/submission.js b/client/src/store/submission.js index c98e0b2fc0..dd9a370571 100644 --- a/client/src/store/submission.js +++ b/client/src/store/submission.js @@ -13,15 +13,15 @@ import { atom } from 'recoil'; const submission = atom({ key: 'submission', - default: null + default: null, }); const isSubmitting = atom({ key: 'isSubmitting', - default: false + default: false, }); export default { submission, - isSubmitting + isSubmitting, }; diff --git a/client/src/store/text.js b/client/src/store/text.js index 7aab98e3e8..7354e07df0 100644 --- a/client/src/store/text.js +++ b/client/src/store/text.js @@ -2,7 +2,7 @@ import { atom } from 'recoil'; const text = atom({ key: 'text', - default: '' + default: '', }); export default { text }; diff --git a/client/src/store/token.js b/client/src/store/token.js index cf5070307f..726659c1be 100644 --- a/client/src/store/token.js +++ b/client/src/store/token.js @@ -2,7 +2,7 @@ import { atom, useRecoilState } from 'recoil'; const tokenRefreshHints = atom({ key: 'tokenRefreshHints', - default: 1 + default: 1, }); const useToken = (endpoint) => { @@ -18,5 +18,5 @@ const useToken = (endpoint) => { }; export default { - useToken + useToken, }; diff --git a/client/src/store/user.js b/client/src/store/user.js index 060df1500b..c4db3cf71a 100644 --- a/client/src/store/user.js +++ b/client/src/store/user.js @@ -2,9 +2,9 @@ import { atom } from 'recoil'; const user = atom({ key: 'user', - default: null + default: null, }); export default { - user + user, }; diff --git a/client/src/utils/cleanupPreset.js b/client/src/utils/cleanupPreset.js index 7c03a154b5..72ce22731e 100644 --- a/client/src/utils/cleanupPreset.js +++ b/client/src/utils/cleanupPreset.js @@ -13,7 +13,7 @@ const cleanupPreset = ({ preset: _preset, endpointsConfig = {} }) => { top_p: _preset?.top_p ?? 1, presence_penalty: _preset?.presence_penalty ?? 0, frequency_penalty: _preset?.frequency_penalty ?? 0, - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } else if (endpoint === 'google') { preset = { @@ -27,7 +27,7 @@ const cleanupPreset = ({ preset: _preset, endpointsConfig = {} }) => { maxOutputTokens: _preset?.maxOutputTokens ?? 1024, topP: _preset?.topP ?? 0.95, topK: _preset?.topK ?? 40, - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } else if (endpoint === 'anthropic') { preset = { @@ -40,7 +40,7 @@ const cleanupPreset = ({ preset: _preset, endpointsConfig = {} }) => { maxOutputTokens: _preset?.maxOutputTokens ?? 1024, topP: _preset?.topP ?? 0.7, topK: _preset?.topK ?? 40, - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } else if (endpoint === 'bingAI') { preset = { @@ -50,7 +50,7 @@ const cleanupPreset = ({ preset: _preset, endpointsConfig = {} }) => { context: _preset?.context ?? null, systemMessage: _preset?.systemMessage ?? null, toneStyle: _preset?.toneStyle ?? 'creative', - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } else if (endpoint === 'chatGPTBrowser') { preset = { @@ -60,7 +60,7 @@ const cleanupPreset = ({ preset: _preset, endpointsConfig = {} }) => { _preset?.model ?? endpointsConfig[endpoint]?.availableModels?.[0] ?? 'text-davinci-002-render-sha', - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } else if (endpoint === 'gptPlugins') { const agentOptions = _preset?.agentOptions ?? { @@ -84,20 +84,20 @@ const cleanupPreset = ({ preset: _preset, endpointsConfig = {} }) => { presence_penalty: _preset?.presence_penalty ?? 0, frequency_penalty: _preset?.frequency_penalty ?? 0, agentOptions, - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } else if (endpoint === null) { preset = { endpoint, presetId: _preset?.presetId || null, - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } else { console.error(`Unknown endpoint ${endpoint}`); preset = { endpoint: null, presetId: _preset?.presetId ?? null, - title: _preset?.title ?? 'New Preset' + title: _preset?.title ?? 'New Preset', }; } diff --git a/client/src/utils/getDefaultConversation.js b/client/src/utils/getDefaultConversation.js index ba1f06222b..36556669aa 100644 --- a/client/src/utils/getDefaultConversation.js +++ b/client/src/utils/getDefaultConversation.js @@ -2,7 +2,7 @@ const buildDefaultConversation = ({ conversation, endpoint, endpointsConfig = {}, - lastConversationSetup = {} + lastConversationSetup = {}, }) => { const lastSelectedModel = JSON.parse(localStorage.getItem('lastSelectedModel')) || {}; const lastSelectedTools = JSON.parse(localStorage.getItem('lastSelectedTools')) || []; @@ -22,7 +22,7 @@ const buildDefaultConversation = ({ temperature: lastConversationSetup?.temperature ?? 1, top_p: lastConversationSetup?.top_p ?? 1, presence_penalty: lastConversationSetup?.presence_penalty ?? 0, - frequency_penalty: lastConversationSetup?.frequency_penalty ?? 0 + frequency_penalty: lastConversationSetup?.frequency_penalty ?? 0, }; } else if (endpoint === 'google') { conversation = { @@ -36,12 +36,12 @@ const buildDefaultConversation = ({ modelLabel: lastConversationSetup?.modelLabel ?? null, promptPrefix: lastConversationSetup?.promptPrefix ?? null, examples: lastConversationSetup?.examples ?? [ - { input: { content: '' }, output: { content: '' } } + { input: { content: '' }, output: { content: '' } }, ], temperature: lastConversationSetup?.temperature ?? 0.2, maxOutputTokens: lastConversationSetup?.maxOutputTokens ?? 1024, topP: lastConversationSetup?.topP ?? 0.95, - topK: lastConversationSetup?.topK ?? 40 + topK: lastConversationSetup?.topK ?? 40, }; } else if (endpoint === 'bingAI') { const { jailbreak, toneStyle } = lastBingSettings; @@ -55,7 +55,7 @@ const buildDefaultConversation = ({ jailbreakConversationId: lastConversationSetup?.jailbreakConversationId ?? null, conversationSignature: null, clientId: null, - invocationId: 1 + invocationId: 1, }; } else if (endpoint === 'anthropic') { conversation = { @@ -71,7 +71,7 @@ const buildDefaultConversation = ({ temperature: lastConversationSetup?.temperature ?? 0.7, maxOutputTokens: lastConversationSetup?.maxOutputTokens ?? 1024, topP: lastConversationSetup?.topP ?? 0.7, - topK: lastConversationSetup?.topK ?? 40 + topK: lastConversationSetup?.topK ?? 40, }; } else if (endpoint === 'chatGPTBrowser') { conversation = { @@ -81,7 +81,7 @@ const buildDefaultConversation = ({ lastConversationSetup?.model ?? lastSelectedModel[endpoint] ?? endpointsConfig[endpoint]?.availableModels?.[0] ?? - 'text-davinci-002-render-sha' + 'text-davinci-002-render-sha', }; } else if (endpoint === 'gptPlugins') { const agentOptions = lastConversationSetup?.agentOptions ?? { @@ -108,18 +108,18 @@ const buildDefaultConversation = ({ top_p: lastConversationSetup?.top_p ?? 1, presence_penalty: lastConversationSetup?.presence_penalty ?? 0, frequency_penalty: lastConversationSetup?.frequency_penalty ?? 0, - agentOptions + agentOptions, }; } else if (endpoint === null) { conversation = { ...conversation, - endpoint + endpoint, }; } else { console.error(`Unknown endpoint ${endpoint}`); conversation = { ...conversation, - endpoint: null + endpoint: null, }; } @@ -137,7 +137,7 @@ const getDefaultConversation = ({ conversation, endpointsConfig, preset }) => { conversation, endpoint, lastConversationSetup: preset, - endpointsConfig + endpointsConfig, }); return conversation; } else { @@ -182,7 +182,7 @@ const getDefaultConversation = ({ conversation, endpointsConfig, preset }) => { 'chatGPTBrowser', 'gptPlugins', 'google', - 'anthropic' + 'anthropic', ].find((e) => endpointsConfig?.[e]); if (endpoint) { conversation = buildDefaultConversation({ conversation, endpoint, endpointsConfig }); diff --git a/client/src/utils/getIcon.jsx b/client/src/utils/getIcon.jsx index c6759a7cc6..5b681e00b1 100644 --- a/client/src/utils/getIcon.jsx +++ b/client/src/utils/getIcon.jsx @@ -13,7 +13,7 @@ const getIcon = (props) => { title={user?.name || 'User'} style={{ width: size, - height: size + height: size, }} className={'relative flex items-center justify-center' + props?.className} > @@ -93,7 +93,7 @@ const getIcon = (props) => { style={{ background: bg || 'transparent', width: size, - height: size + height: size, }} className={cn( 'relative flex items-center justify-center rounded-sm text-white ', diff --git a/client/src/utils/handleSubmit.js b/client/src/utils/handleSubmit.js index 4860ba4089..c9e68dc908 100644 --- a/client/src/utils/handleSubmit.js +++ b/client/src/utils/handleSubmit.js @@ -17,7 +17,7 @@ const useMessageHandler = () => { const ask = ( { text, parentMessageId = null, conversationId = null, messageId = null }, - { isRegenerate = false } = {} + { isRegenerate = false } = {}, ) => { if (!!isSubmitting || text === '') { return; @@ -40,7 +40,7 @@ const useMessageHandler = () => { top_p: currentConversation?.top_p ?? 1, presence_penalty: currentConversation?.presence_penalty ?? 0, frequency_penalty: currentConversation?.frequency_penalty ?? 0, - token: endpointsConfig[endpoint]?.userProvide ? getToken() : null + token: endpointsConfig[endpoint]?.userProvide ? getToken() : null, }; responseSender = endpointOption.chatGptLabel ?? 'ChatGPT'; } else if (endpoint === 'google') { @@ -53,13 +53,13 @@ const useMessageHandler = () => { modelLabel: currentConversation?.modelLabel ?? null, promptPrefix: currentConversation?.promptPrefix ?? null, examples: currentConversation?.examples ?? [ - { input: { content: '' }, output: { content: '' } } + { input: { content: '' }, output: { content: '' } }, ], temperature: currentConversation?.temperature ?? 0.2, maxOutputTokens: currentConversation?.maxOutputTokens ?? 1024, topP: currentConversation?.topP ?? 0.95, topK: currentConversation?.topK ?? 40, - token: endpointsConfig[endpoint]?.userProvide ? getToken() : null + token: endpointsConfig[endpoint]?.userProvide ? getToken() : null, }; responseSender = endpointOption.chatGptLabel ?? 'ChatGPT'; } else if (endpoint === 'bingAI') { @@ -73,7 +73,7 @@ const useMessageHandler = () => { conversationSignature: currentConversation?.conversationSignature ?? null, clientId: currentConversation?.clientId ?? null, invocationId: currentConversation?.invocationId ?? 1, - token: endpointsConfig[endpoint]?.userProvide ? getToken() : null + token: endpointsConfig[endpoint]?.userProvide ? getToken() : null, }; responseSender = endpointOption.jailbreak ? 'Sydney' : 'BingAI'; } else if (endpoint === 'anthropic') { @@ -89,7 +89,7 @@ const useMessageHandler = () => { maxOutputTokens: currentConversation?.maxOutputTokens ?? 1024, topP: currentConversation?.topP ?? 0.7, topK: currentConversation?.topK ?? 40, - token: endpointsConfig[endpoint]?.userProvide ? getToken() : null + token: endpointsConfig[endpoint]?.userProvide ? getToken() : null, }; responseSender = 'Anthropic'; } else if (endpoint === 'chatGPTBrowser') { @@ -99,7 +99,7 @@ const useMessageHandler = () => { currentConversation?.model ?? endpointsConfig[endpoint]?.availableModels?.[0] ?? 'text-davinci-002-render-sha', - token: endpointsConfig[endpoint]?.userProvide ? getToken() : null + token: endpointsConfig[endpoint]?.userProvide ? getToken() : null, }; responseSender = 'ChatGPT'; } else if (endpoint === 'gptPlugins') { @@ -123,7 +123,7 @@ const useMessageHandler = () => { presence_penalty: currentConversation?.presence_penalty ?? 0, frequency_penalty: currentConversation?.frequency_penalty ?? 0, token: endpointsConfig[endpoint]?.userProvide ? getToken() : null, - agentOptions + agentOptions, }; responseSender = 'ChatGPT'; } else if (endpoint === null) { @@ -159,7 +159,7 @@ const useMessageHandler = () => { isCreatedByUser: true, parentMessageId, conversationId, - messageId: fakeMessageId + messageId: fakeMessageId, }; // construct the placeholder response message @@ -170,22 +170,22 @@ const useMessageHandler = () => { messageId: (isRegenerate ? messageId : fakeMessageId) + '_', conversationId, unfinished: endpoint === 'azureOpenAI' || endpoint === 'openAI' ? false : true, - submitting: true + submitting: true, }; const submission = { conversation: { ...currentConversation, - conversationId + conversationId, }, endpointOption, message: { ...currentMsg, - overrideParentMessageId: isRegenerate ? messageId : null + overrideParentMessageId: isRegenerate ? messageId : null, }, messages: currentMessages, isRegenerate, - initialResponse + initialResponse, }; console.log('User Input:', text, submission); @@ -205,7 +205,7 @@ const useMessageHandler = () => { ask({ ...parentMessage }, { isRegenerate: true }); else console.error( - 'Failed to regenerate the message: parentMessage not found or not created by user.' + 'Failed to regenerate the message: parentMessage not found or not created by user.', ); }; diff --git a/client/src/utils/index.jsx b/client/src/utils/index.jsx index 85286033bd..b65ee44dd3 100644 --- a/client/src/utils/index.jsx +++ b/client/src/utils/index.jsx @@ -32,7 +32,7 @@ export const languages = [ 'x86asm', 'matlab', 'perl', - 'pascal' + 'pascal', ]; export const alternateName = { diff --git a/client/src/utils/resetConvo.js b/client/src/utils/resetConvo.js index 8ce01fda57..9b047e4ef2 100644 --- a/client/src/utils/resetConvo.js +++ b/client/src/utils/resetConvo.js @@ -13,7 +13,7 @@ export default function resetConvo(messages, sender) { 'last model: ', lastModel, 'sender: ', - sender + sender, ); return true; } diff --git a/client/vite.config.ts b/client/vite.config.ts index a6a69f82c8..98356675ba 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -12,13 +12,13 @@ export default defineConfig({ proxy: { '/api': { target: 'http://localhost:3080', - changeOrigin: true + changeOrigin: true, }, '/oauth': { target: 'http://localhost:3080', - changeOrigin: true - } - } + changeOrigin: true, + }, + }, }, // All other env variables are filtered out envDir: '../', @@ -35,15 +35,15 @@ export default defineConfig({ if (id.includes('node_modules')) { return 'vendor'; } - } - } - } + }, + }, + }, }, resolve: { alias: { - '~': path.join(__dirname, 'src/') - } - } + '~': path.join(__dirname, 'src/'), + }, + }, }); interface SourcemapExclude { @@ -57,10 +57,10 @@ export function sourcemapExclude(opts?: SourcemapExclude): Plugin { return { code, // https://github.com/rollup/rollup/blob/master/docs/plugin-development/index.md#source-code-transformations - map: { mappings: '' } + map: { mappings: '' }, }; } - } + }, }; } @@ -69,7 +69,7 @@ function htmlPlugin(env: ReturnType) { name: 'html-transform', transformIndexHtml: { enforce: 'pre' as const, - transform: (html: string): string => html.replace(/%(.*?)%/g, (match, p1) => env[p1] ?? match) - } + transform: (html: string): string => html.replace(/%(.*?)%/g, (match, p1) => env[p1] ?? match), + }, }; } diff --git a/config/create-user.js b/config/create-user.js index b9cb9c5cdf..f58ac77ed8 100644 --- a/config/create-user.js +++ b/config/create-user.js @@ -1,8 +1,8 @@ -const connectDb = require("@librechat/backend/lib/db/connectDb"); -const migrateDb = require("@librechat/backend/lib/db/migrateDb"); -const { registerUser } = require("@librechat/backend/server/services/auth.service"); -const { askQuestion } = require("./helpers"); -const User = require("@librechat/backend/models/User"); +const connectDb = require('@librechat/backend/lib/db/connectDb'); +const migrateDb = require('@librechat/backend/lib/db/migrateDb'); +const { registerUser } = require('@librechat/backend/server/services/auth.service'); +const { askQuestion } = require('./helpers'); +const User = require('@librechat/backend/models/User'); const silentExit = (code = 0) => { console.log = () => {}; @@ -130,6 +130,6 @@ const silentExit = (code = 0) => { } // Done! - console.green("User created successfully!") + console.green('User created successfully!') silentExit(0); })(); \ No newline at end of file diff --git a/config/helpers.js b/config/helpers.js index 661342163d..fdb8117900 100644 --- a/config/helpers.js +++ b/config/helpers.js @@ -2,7 +2,7 @@ * Helper functions * This allows us to give the console some colour when running in a terminal */ -const readline = require("readline"); +const readline = require('readline'); const askQuestion = (query) => { const rl = readline.createInterface({ @@ -11,10 +11,10 @@ const askQuestion = (query) => { }); return new Promise((resolve) => - rl.question("\x1b[36m" + query + "\n> " + "\x1b[0m", (ans) => { + rl.question('\x1b[36m' + query + '\n> ' + '\x1b[0m', (ans) => { rl.close(); resolve(ans); - }) + }), ); }; diff --git a/config/install.js b/config/install.js index ba7baa5882..d70a9e617a 100644 --- a/config/install.js +++ b/config/install.js @@ -58,29 +58,29 @@ let env = {}; // Ask for the app title const title = await askQuestion( - 'Enter the app title (default: "LibreChat"): ' + 'Enter the app title (default: "LibreChat"): ', ); env['APP_TITLE'] = title || 'LibreChat'; // Ask for OPENAI_API_KEY const key = await askQuestion( - 'Enter your OPENAI_API_KEY (default: "user_provided"): ' + 'Enter your OPENAI_API_KEY (default: "user_provided"): ', ); env['OPENAI_API_KEY'] = key || 'user_provided'; // GPT4??? const gpt4 = await askQuestion( - 'Do you have access to the GPT4 api (y/n)? Default: n' + 'Do you have access to the GPT4 api (y/n)? Default: n', ); if (gpt4 == 'y' || gpt4 == 'yes') { - env['OPENAI_MODELS'] = "gpt-3.5-turbo,gpt-3.5-turbo-0301,text-davinci-003,gpt-4,gpt-4-0314" + env['OPENAI_MODELS'] = 'gpt-3.5-turbo,gpt-3.5-turbo-0301,text-davinci-003,gpt-4,gpt-4-0314' } else { - env['OPENAI_MODELS'] = "gpt-3.5-turbo,gpt-3.5-turbo-0301,text-davinci-003" + env['OPENAI_MODELS'] = 'gpt-3.5-turbo,gpt-3.5-turbo-0301,text-davinci-003' } // Ask about mongodb const mongodb = await askQuestion( - 'What is your mongodb url? (default: mongodb://127.0.0.1:27017/LibreChat)' + 'What is your mongodb url? (default: mongodb://127.0.0.1:27017/LibreChat)', ); env['MONGO_URI'] = mongodb || 'mongodb://127.0.0.1:27017/LibreChat'; // Very basic check to make sure they entered a url @@ -90,7 +90,7 @@ let env = {}; // Lets ask about open registration const openReg = await askQuestion( - 'Do you want to allow user registration (y/n)? Default: y' + 'Do you want to allow user registration (y/n)? Default: y', ); if (openReg === 'n' || openReg === 'no') { env['ALLOW_REGISTRATION'] = 'false'; diff --git a/config/loader.js b/config/loader.js index 9c000bb6a3..99f3e28eb6 100644 --- a/config/loader.js +++ b/config/loader.js @@ -40,7 +40,7 @@ class Env { } else { console.warn('The default .env file was not found'); } - + const environment = this.currentEnvironment(); // Load the environment specific env file @@ -95,8 +95,8 @@ class Env { /** * Resolve the location of the env file * - * @param {String} envFile - * @returns + * @param {String} envFile + * @returns */ resolve(envFile) { return path.resolve(process.cwd(), envFile); @@ -157,7 +157,7 @@ class Env { } // Skip lines with quotes and numbers already // Todo: this could be one regex - const wrappedValue = value.includes(' ') && ! value.includes('"') && ! value.includes("'") && !/\d/.test(value) ? `"${value}"` : value; + const wrappedValue = value.includes(' ') && ! value.includes('"') && ! value.includes('\'') && !/\d/.test(value) ? `"${value}"` : value; return `${key}=${wrappedValue}`; }); @@ -165,12 +165,11 @@ class Env { fs.writeFileSync(filePath, updatedContent); } - /** * Generate Secure Random Strings * * @param {Number} length The length of the random string - * @returns + * @returns */ generateSecureRandomString(length = 32) { return crypto.randomBytes(length).toString('hex'); @@ -186,8 +185,8 @@ class Env { /** * Get an environment variable * - * @param {String} variable - * @returns + * @param {String} variable + * @returns */ get(variable) { return process.env[variable]; diff --git a/config/upgrade.js b/config/upgrade.js index 8a2f6dd06b..5a3e55b900 100644 --- a/config/upgrade.js +++ b/config/upgrade.js @@ -48,9 +48,9 @@ if (!fs.existsSync(clientEnvPath)) { /** * Refactor the ENV if it has a prod_/dev_ version * - * @param {*} varDev - * @param {*} varProd - * @param {*} varName + * @param {*} varDev + * @param {*} varProd + * @param {*} varName */ function refactorPairedEnvVar(varDev, varProd, varName) { // Lets validate if either of these are undefined, if so lets use the non-undefined one @@ -103,7 +103,7 @@ const removeEnvs = { '# Don\'t forget to set Node env to development in the Server configuration section above': 'remove', '# if you want to run in dev mode': 'remove', '# Change these values to domain if deploying:': 'remove', - '# Set Node env to development if running in dev mode.': 'remove' + '# Set Node env to development if running in dev mode.': 'remove', } loader.writeEnvFile(rootEnvPath, removeEnvs) @@ -119,13 +119,13 @@ loader.addSecureEnvVar(rootEnvPath, 'CREDS_IV', 16); loader.addSecureEnvVar(rootEnvPath, 'JWT_SECRET', 32); // Lets update the openai key name, not the best spot in the env file but who cares ¯\_(ツ)_/¯ -loader.writeEnvFile(rootEnvPath, {'OPENAI_API_KEY': initEnv['OPENAI_KEY']}) +loader.writeEnvFile(rootEnvPath, { 'OPENAI_API_KEY': initEnv['OPENAI_KEY'] }) // TODO: we need to copy over the value of: APP_TITLE fs.appendFileSync(rootEnvPath, '\n\n##########################\n# Frontend Vite Variables:\n##########################\n'); const frontend = { 'APP_TITLE': initEnv['VITE_APP_TITLE'] || '"LibreChat"', - 'ALLOW_REGISTRATION': 'true' + 'ALLOW_REGISTRATION': 'true', } loader.writeEnvFile(rootEnvPath, frontend) diff --git a/docs/dev/eslintrc-stripped.js b/docs/dev/eslintrc-stripped.js index 95af5567d3..06c9aca83d 100644 --- a/docs/dev/eslintrc-stripped.js +++ b/docs/dev/eslintrc-stripped.js @@ -4,7 +4,7 @@ module.exports = { es2021: true, node: true, commonjs: true, - es6: true + es6: true, }, extends: ['prettier'], parser: '@typescript-eslint/parser', @@ -12,8 +12,8 @@ module.exports = { ecmaVersion: 'latest', sourceType: 'module', ecmaFeatures: { - jsx: true - } + jsx: true, + }, }, plugins: ['react', 'react-hooks', '@typescript-eslint'], rules: { @@ -25,8 +25,8 @@ module.exports = { code: 150, ignoreStrings: true, ignoreTemplateLiterals: true, - ignoreComments: true - } + ignoreComments: true, + }, ], 'linebreak-style': 0, // 'arrow-parens': [2, 'as-needed', { requireForBlockBody: true }], @@ -38,7 +38,7 @@ module.exports = { 'no-continue': 'off', 'no-restricted-syntax': 'off', 'react/prop-types': ['off'], - 'react/display-name': ['off'] + 'react/display-name': ['off'], }, overrides: [ { @@ -46,14 +46,14 @@ module.exports = { rules: { 'no-unused-vars': 'off', // off because it conflicts with '@typescript-eslint/no-unused-vars' 'react/display-name': 'off', - '@typescript-eslint/no-unused-vars': 'warn' - } + '@typescript-eslint/no-unused-vars': 'warn', + }, }, { files: ['rollup.config.js', '.eslintrc.js', 'jest.config.js'], env: { - node: true - } + node: true, + }, }, { files: [ @@ -65,18 +65,18 @@ module.exports = { '**/*.spec.jsx', '**/*.spec.ts', '**/*.spec.tsx', - 'setupTests.js' + 'setupTests.js', ], env: { jest: true, - node: true + node: true, }, rules: { 'react/display-name': 'off', 'react/prop-types': 'off', - 'react/no-unescaped-entities': 'off' - } - } + 'react/no-unescaped-entities': 'off', + }, + }, ], settings: { react: { @@ -84,7 +84,7 @@ module.exports = { // default to "createReactClass" pragma: 'React', // Pragma to use, default to "React" fragment: 'Fragment', // Fragment to use (may be a property of ), default to "Fragment" - version: 'detect' // React version. "detect" automatically picks the version you have installed. - } - } + version: 'detect', // React version. "detect" automatically picks the version you have installed. + }, + }, }; diff --git a/e2e/playwright.config.local.ts b/e2e/playwright.config.local.ts index a3746e8578..4ba2b7dbf2 100644 --- a/e2e/playwright.config.local.ts +++ b/e2e/playwright.config.local.ts @@ -1,4 +1,4 @@ -import {PlaywrightTestConfig} from '@playwright/test'; +import { PlaywrightTestConfig } from '@playwright/test'; import mainConfig from './playwright.config'; const config: PlaywrightTestConfig = { diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index 880e58c669..446f2d0839 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -5,8 +5,8 @@ export default defineConfig({ globalSetup: require.resolve('./setup/global-setup'), testDir: 'specs/', outputDir: 'specs/.test-results', - /* Run tests in files in parallel. - NOTE: This sometimes causes issues on Windows. + /* Run tests in files in parallel. + NOTE: This sometimes causes issues on Windows. Set to false if you experience issues running on a Windows machine. */ fullyParallel: true, /* Fail the build on CI if you accidentally left test.only in the source code. */ @@ -25,16 +25,16 @@ export default defineConfig({ ignoreHTTPSErrors: true, headless: true, storageState: path.resolve('./e2e/storageState.json'), - screenshot: 'only-on-failure' + screenshot: 'only-on-failure', }, expect: { - timeout: 10000 + timeout: 10000, }, /* Configure projects for major browsers */ projects: [ { name: 'chromium', - use: { ...devices['Desktop Chrome'] } + use: { ...devices['Desktop Chrome'] }, }, /* Test against mobile viewports. */ // { @@ -53,6 +53,6 @@ export default defineConfig({ port: 3080, // url: 'http://localhost:3080', timeout: 30_000, - reuseExistingServer: true + reuseExistingServer: true, }, }); diff --git a/e2e/setup/authenticate.ts b/e2e/setup/authenticate.ts index 9bb9467a4d..ee7dd4c338 100644 --- a/e2e/setup/authenticate.ts +++ b/e2e/setup/authenticate.ts @@ -1,4 +1,4 @@ -import {Page, FullConfig, chromium} from '@playwright/test'; +import { Page, FullConfig, chromium } from '@playwright/test'; type User = {username: string; password: string}; @@ -10,7 +10,7 @@ async function login(page: Page, user: User) { async function authenticate(config: FullConfig, user: User) { console.log('🤖: global setup has been started'); - const {baseURL, storageState} = config.projects[0].use; + const { baseURL, storageState } = config.projects[0].use; console.log('🤖: using baseURL', baseURL); const browser = await chromium.launch(); const page = await browser.newPage(); @@ -24,7 +24,7 @@ async function authenticate(config: FullConfig, user: User) { localStorage.setItem('navVisible', 'true'); }); console.log('🤖: ✔️ localStorage: set Nav as Visible', storageState); - await page.context().storageState({path: storageState as string}); + await page.context().storageState({ path: storageState as string }); console.log('🤖: ✔️ authentication state successfully saved in', storageState); await browser.close(); console.log('🤖: global setup has been finished'); diff --git a/e2e/setup/global-setup.local.ts b/e2e/setup/global-setup.local.ts index 916df777e8..2bbb197389 100644 --- a/e2e/setup/global-setup.local.ts +++ b/e2e/setup/global-setup.local.ts @@ -1,4 +1,4 @@ -import {FullConfig} from '@playwright/test'; +import { FullConfig } from '@playwright/test'; import localUser from '../config.local'; import authenticate from './authenticate'; diff --git a/e2e/setup/global-setup.ts b/e2e/setup/global-setup.ts index 15bfbd0125..73ff9839af 100644 --- a/e2e/setup/global-setup.ts +++ b/e2e/setup/global-setup.ts @@ -1,4 +1,4 @@ -import {FullConfig} from '@playwright/test'; +import { FullConfig } from '@playwright/test'; import authenticate from './authenticate'; async function globalSetup(config: FullConfig) { diff --git a/e2e/specs/landing.spec.js b/e2e/specs/landing.spec.js index b4fd1f09e1..7b62c81d70 100644 --- a/e2e/specs/landing.spec.js +++ b/e2e/specs/landing.spec.js @@ -3,7 +3,7 @@ import { expect, test } from '@playwright/test'; test.describe('Landing suite', () => { - test('Landing title', async ({page}) => { + test('Landing title', async ({ page }) => { await page.goto('http://localhost:3080/'); const pageTitle = await page.textContent('#landing-title'); expect(pageTitle.length).toBeGreaterThan(0); diff --git a/e2e/specs/messages.spec.js b/e2e/specs/messages.spec.js index ff60e8b532..5ab5c3a4b8 100644 --- a/e2e/specs/messages.spec.js +++ b/e2e/specs/messages.spec.js @@ -10,7 +10,7 @@ function isUUID(uuid) { test.describe('Messaging suite', () => { - test('textbox should be focused after receiving message & test expected navigation', async ({page}) => { + test('textbox should be focused after receiving message & test expected navigation', async ({ page }) => { test.setTimeout(120000); const message = 'hi'; const endpoint = endpoints[1]; @@ -26,12 +26,12 @@ test.describe('Messaging suite', () => { page.waitForResponse(async (response) => { return response.url().includes(`/api/ask/${endpoint}`) && response.status() === 200; }), - page.locator('form').getByRole('textbox').press('Enter') + page.locator('form').getByRole('textbox').press('Enter'), ]; const [response] = await Promise.all(responsePromise); const responseBody = await response.body(); - const messageSuccess = responseBody.includes(`"final":true`); + const messageSuccess = responseBody.includes('"final":true'); expect(messageSuccess).toBe(true); // Check if textbox is focused diff --git a/e2e/specs/settings.spec.js b/e2e/specs/settings.spec.js index a2c7b1f553..b425718725 100644 --- a/e2e/specs/settings.spec.js +++ b/e2e/specs/settings.spec.js @@ -15,13 +15,13 @@ test.describe('Settings suite', () => { const button2 = await page.getByRole('button', { name: 'Mode: Sydney' }); try { - await button1.click({ timeout: 100}); + await button1.click({ timeout: 100 }); } catch (e) { // console.log('Bing button', e); } try { - await button2.click({ timeout: 100}); + await button2.click({ timeout: 100 }); } catch (e) { // console.log('Sydney button', e); } diff --git a/lint-staged.config.js b/lint-staged.config.js index 5400086dec..482e1f050e 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,4 +1,4 @@ module.exports = { - '*.{js,jsx,ts,tsx}': ['eslint --fix', 'eslint'], - '*.json': ['prettier --write'] + '*.{js,jsx,ts,tsx}': ['prettier --write', 'eslint --fix', 'eslint'], + '*.json': ['prettier --write'], }; diff --git a/package.json b/package.json index fec617b50a..caa649a49c 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "e2e:update": "playwright test --config=e2e/playwright.config.js --update-snapshots", "e2e:report": "npx playwright show-report e2e/playwright-report", "prepare": "node config/prepare.js", + "lint:fix": "eslint --fix \"{,!(node_modules)/**/}*.{js,jsx,ts,tsx}\"", + "lint": "eslint \"{,!(node_modules)/**/}*.{js,jsx,ts,tsx}\"", "format": "prettier-eslint --write \"{,!(node_modules)/**/}*.{js,jsx,ts,tsx}\"" }, "repository": { diff --git a/packages/data-provider/babel.config.js b/packages/data-provider/babel.config.js index 82cf589024..7d5344d252 100644 --- a/packages/data-provider/babel.config.js +++ b/packages/data-provider/babel.config.js @@ -1,4 +1,4 @@ module.exports = { - presets: [['@babel/preset-env', {targets: {node: 'current'}}], '@babel/preset-typescript'], + presets: [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript'], plugins: ['babel-plugin-replace-ts-export-assignment'], }; diff --git a/packages/data-provider/jest.config.js b/packages/data-provider/jest.config.js index 9b19ec82ad..6b8c4abe79 100644 --- a/packages/data-provider/jest.config.js +++ b/packages/data-provider/jest.config.js @@ -14,5 +14,5 @@ module.exports = { // lines: 57, // }, // }, - restoreMocks: true + restoreMocks: true, }; diff --git a/packages/data-provider/rollup.config.js b/packages/data-provider/rollup.config.js index 869c44f87b..5ff739fce9 100644 --- a/packages/data-provider/rollup.config.js +++ b/packages/data-provider/rollup.config.js @@ -24,7 +24,7 @@ export default [ preserveSymlinks: true, plugins: [ resolve(), - typescript({useTsconfigDeclarationDir: true, tsconfig: './tsconfig.json'}), + typescript({ useTsconfigDeclarationDir: true, tsconfig: './tsconfig.json' }), ], }, }, diff --git a/packages/data-provider/src/api-endpoints.ts b/packages/data-provider/src/api-endpoints.ts index 3fdbd43eb7..fe1579cd54 100644 --- a/packages/data-provider/src/api-endpoints.ts +++ b/packages/data-provider/src/api-endpoints.ts @@ -1,9 +1,9 @@ export const user = () => { - return `/api/user`; + return '/api/user'; }; export const userPlugins = () => { - return `/api/user/plugins`; + return '/api/user/plugins'; }; export const messages = (id: string) => { @@ -23,11 +23,11 @@ export const conversationById = (id: string) => { }; export const updateConversation = () => { - return `/api/convos/update`; + return '/api/convos/update'; }; export const deleteConversation = () => { - return `/api/convos/clear`; + return '/api/convos/clear'; }; export const search = (q: string, pageNumber: string) => { @@ -35,23 +35,23 @@ export const search = (q: string, pageNumber: string) => { }; export const searchEnabled = () => { - return `/api/search/enable`; + return '/api/search/enable'; }; export const presets = () => { - return `/api/presets`; + return '/api/presets'; }; export const deletePreset = () => { - return `/api/presets/delete`; + return '/api/presets/delete'; }; export const aiEndpoints = () => { - return `/api/endpoints`; + return '/api/endpoints'; }; export const tokenizer = () => { - return `/api/tokenizer`; + return '/api/tokenizer'; }; export const login = () => { @@ -92,4 +92,4 @@ export const plugins = () => { export const config = () => { return '/api/config'; -} +}; diff --git a/packages/data-provider/src/createPayload.ts b/packages/data-provider/src/createPayload.ts index 6808e9e14f..4372416fcd 100644 --- a/packages/data-provider/src/createPayload.ts +++ b/packages/data-provider/src/createPayload.ts @@ -21,8 +21,8 @@ export default function createPayload(submission: TSubmission) { const payload = { ...message, ...endpointOption, - conversationId + conversationId, }; return { server, payload }; -} \ No newline at end of file +} diff --git a/packages/data-provider/src/data-service.ts b/packages/data-provider/src/data-service.ts index 220742a66a..0f38578019 100644 --- a/packages/data-provider/src/data-service.ts +++ b/packages/data-provider/src/data-service.ts @@ -9,7 +9,7 @@ export function getConversations(pageNumber: string): Promise { return request.post(endpoints.abortRequest(endpoint), { arg: { abortKey, message } }); } @@ -32,7 +32,7 @@ export function getConversationById(id: string): Promise { } export function updateConversation( - payload: t.TUpdateConversationRequest + payload: t.TUpdateConversationRequest, ): Promise { return request.post(endpoints.updateConversation(), { arg: payload }); } @@ -63,7 +63,7 @@ export function getUser(): Promise { export const searchConversations = async ( q: string, - pageNumber: string + pageNumber: string, ): Promise => { return request.get(endpoints.search(q, pageNumber)); }; @@ -96,7 +96,9 @@ export const getLoginGoogle = () => { return request.get(endpoints.loginGoogle()); }; -export const requestPasswordReset = (payload: t.TRequestPasswordReset): Promise => { +export const requestPasswordReset = ( + payload: t.TRequestPasswordReset, +): Promise => { return request.post(endpoints.requestPasswordReset(), payload); }; @@ -114,4 +116,4 @@ export const updateUserPlugins = (payload: t.TUpdateUserPlugins) => { export const getStartupConfig = (): Promise => { return request.get(endpoints.config()); -} +}; diff --git a/packages/data-provider/src/react-query-service.ts b/packages/data-provider/src/react-query-service.ts index 89e411beb5..01c13c36bd 100644 --- a/packages/data-provider/src/react-query-service.ts +++ b/packages/data-provider/src/react-query-service.ts @@ -4,7 +4,7 @@ import { useMutation, useQueryClient, UseMutationResult, - QueryObserverResult + QueryObserverResult, } from '@tanstack/react-query'; import * as t from './types'; import * as dataService from './data-service'; @@ -29,25 +29,25 @@ export const useAbortRequestWithMessage = (): UseMutationResult< { endpoint: string; abortKey: string; message: string } > => { return useMutation(({ endpoint, abortKey, message }) => - dataService.abortRequestWithMessage(endpoint, abortKey, message) + dataService.abortRequestWithMessage(endpoint, abortKey, message), ); }; export const useGetUserQuery = ( - config?: UseQueryOptions + config?: UseQueryOptions, ): QueryObserverResult => { return useQuery([QueryKeys.user], () => dataService.getUser(), { refetchOnWindowFocus: false, refetchOnReconnect: false, refetchOnMount: false, retry: false, - ...config + ...config, }); }; export const useGetMessagesByConvoId = ( id: string, - config?: UseQueryOptions + config?: UseQueryOptions, ): QueryObserverResult => { return useQuery( [QueryKeys.messages, id], @@ -56,14 +56,14 @@ export const useGetMessagesByConvoId = ( refetchOnWindowFocus: false, refetchOnReconnect: false, refetchOnMount: false, - ...config - } + ...config, + }, ); }; export const useGetConversationByIdQuery = ( id: string, - config?: UseQueryOptions + config?: UseQueryOptions, ): QueryObserverResult => { return useQuery( [QueryKeys.conversation, id], @@ -72,8 +72,8 @@ export const useGetConversationByIdQuery = ( refetchOnWindowFocus: false, refetchOnReconnect: false, refetchOnMount: false, - ...config - } + ...config, + }, ); }; @@ -85,12 +85,12 @@ export const useGetConversationByIdMutation = (id: string): UseMutationResult { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.conversation, id]); - } + }, }); }; export const useUpdateConversationMutation = ( - id: string + id: string, ): UseMutationResult< t.TUpdateConversationResponse, unknown, @@ -104,13 +104,13 @@ export const useUpdateConversationMutation = ( onSuccess: () => { queryClient.invalidateQueries([QueryKeys.conversation, id]); queryClient.invalidateQueries([QueryKeys.allConversations]); - } - } + }, + }, ); }; export const useDeleteConversationMutation = ( - id?: string + id?: string, ): UseMutationResult< t.TDeleteConversationResponse, unknown, @@ -124,8 +124,8 @@ export const useDeleteConversationMutation = ( onSuccess: () => { queryClient.invalidateQueries([QueryKeys.conversation, id]); queryClient.invalidateQueries([QueryKeys.allConversations]); - } - } + }, + }, ); }; @@ -134,13 +134,13 @@ export const useClearConversationsMutation = (): UseMutationResult => { return useMutation(() => dataService.clearAllConversations(), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.allConversations]); - } + }, }); }; export const useGetConversationsQuery = ( pageNumber: string, - config?: UseQueryOptions + config?: UseQueryOptions, ): QueryObserverResult => { return useQuery( [QueryKeys.allConversations, pageNumber], @@ -149,19 +149,19 @@ export const useGetConversationsQuery = ( refetchOnReconnect: false, refetchOnMount: false, retry: 1, - ...config - } + ...config, + }, ); }; export const useGetSearchEnabledQuery = ( - config?: UseQueryOptions + config?: UseQueryOptions, ): QueryObserverResult => { return useQuery([QueryKeys.searchEnabled], () => dataService.getSearchEnabled(), { refetchOnWindowFocus: false, refetchOnReconnect: false, refetchOnMount: false, - ...config + ...config, }); }; @@ -169,7 +169,7 @@ export const useGetEndpointsQuery = (): QueryObserverResult => { return useQuery([QueryKeys.endpoints], () => dataService.getAIEndpoints(), { refetchOnWindowFocus: false, refetchOnReconnect: false, - refetchOnMount: false + refetchOnMount: false, }); }; @@ -183,7 +183,7 @@ export const useCreatePresetMutation = (): UseMutationResult< return useMutation((payload: t.TPreset) => dataService.createPreset(payload), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.presets]); - } + }, }); }; @@ -197,18 +197,18 @@ export const useUpdatePresetMutation = (): UseMutationResult< return useMutation((payload: t.TPreset) => dataService.updatePreset(payload), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.presets]); - } + }, }); }; export const useGetPresetsQuery = ( - config?: UseQueryOptions + config?: UseQueryOptions, ): QueryObserverResult => { return useQuery([QueryKeys.presets], () => dataService.getPresets(), { refetchOnWindowFocus: false, refetchOnReconnect: false, refetchOnMount: false, - ...config + ...config, }); }; @@ -222,14 +222,14 @@ export const useDeletePresetMutation = (): UseMutationResult< return useMutation((payload: t.TPreset | object) => dataService.deletePreset(payload), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.presets]); - } + }, }); }; export const useSearchQuery = ( searchQuery: string, pageNumber: string, - config?: UseQueryOptions + config?: UseQueryOptions, ): QueryObserverResult => { return useQuery( [QueryKeys.searchResults, pageNumber, searchQuery], @@ -238,8 +238,8 @@ export const useSearchQuery = ( refetchOnWindowFocus: false, refetchOnReconnect: false, refetchOnMount: false, - ...config - } + ...config, + }, ); }; @@ -253,7 +253,7 @@ export const useUpdateTokenCountMutation = (): UseMutationResult< return useMutation((text: string) => dataService.updateTokenCount(text), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.tokenCount]); - } + }, }); }; @@ -267,7 +267,7 @@ export const useLoginUserMutation = (): UseMutationResult< return useMutation((payload: t.TLoginUser) => dataService.login(payload), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.user]); - } + }, }); }; @@ -281,7 +281,7 @@ export const useRegisterUserMutation = (): UseMutationResult< return useMutation((payload: t.TRegisterUser) => dataService.register(payload), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.user]); - } + }, }); }; @@ -290,7 +290,7 @@ export const useLogoutUserMutation = (): UseMutationResult => { return useMutation(() => dataService.logout(), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.user]); - } + }, }); }; @@ -303,9 +303,14 @@ export const useRefreshTokenMutation = (): UseMutationResult< return useMutation(() => dataService.refreshToken(), {}); }; -export const useRequestPasswordResetMutation = (): UseMutationResult => { +export const useRequestPasswordResetMutation = (): UseMutationResult< + t.TRequestPasswordResetResponse, + unknown, + t.TRequestPasswordReset, + unknown +> => { return useMutation((payload: t.TRequestPasswordReset) => - dataService.requestPasswordReset(payload) + dataService.requestPasswordReset(payload), ); }; @@ -325,8 +330,8 @@ export const useAvailablePluginsQuery = (): QueryObserverResult => { refetchOnWindowFocus: false, refetchOnReconnect: false, - refetchOnMount: false - } + refetchOnMount: false, + }, ); }; @@ -340,14 +345,18 @@ export const useUpdateUserPluginsMutation = (): UseMutationResult< return useMutation((payload: t.TUpdateUserPlugins) => dataService.updateUserPlugins(payload), { onSuccess: () => { queryClient.invalidateQueries([QueryKeys.user]); - } + }, }); }; export const useGetStartupConfig = (): QueryObserverResult => { - return useQuery([QueryKeys.startupConfig], () => dataService.getStartupConfig(), { - refetchOnWindowFocus: false, - refetchOnReconnect: false, - refetchOnMount: false - }); -} + return useQuery( + [QueryKeys.startupConfig], + () => dataService.getStartupConfig(), + { + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, + }, + ); +}; diff --git a/packages/data-provider/src/request.ts b/packages/data-provider/src/request.ts index b2eb1701a8..07e93e76ad 100644 --- a/packages/data-provider/src/request.ts +++ b/packages/data-provider/src/request.ts @@ -7,7 +7,7 @@ async function _get(url: string, options?: AxiosRequestConfig): Promise { async function _post(url: string, data?: any) { const response = await axios.post(url, JSON.stringify(data), { - headers: { 'Content-Type': 'application/json' } + headers: { 'Content-Type': 'application/json' }, }); return response.data; } @@ -15,14 +15,14 @@ async function _post(url: string, data?: any) { async function _postMultiPart(url: string, formData: FormData, options?: AxiosRequestConfig) { const response = await axios.post(url, formData, { ...options, - headers: { 'Content-Type': 'multipart/form-data' } + headers: { 'Content-Type': 'multipart/form-data' }, }); return response.data; } async function _put(url: string, data?: any) { const response = await axios.put(url, JSON.stringify(data), { - headers: { 'Content-Type': 'application/json' } + headers: { 'Content-Type': 'application/json' }, }); return response.data; } @@ -39,7 +39,7 @@ async function _deleteWithOptions(url: string, options?: AxiosRequestConfig): async function _patch(url: string, data?: any) { const response = await axios.patch(url, JSON.stringify(data), { - headers: { 'Content-Type': 'application/json' } + headers: { 'Content-Type': 'application/json' }, }); return response.data; } @@ -51,5 +51,5 @@ export default { put: _put, delete: _delete, deleteWithOptions: _deleteWithOptions, - patch: _patch + patch: _patch, };