diff --git a/api/app/clients/OpenAIClient.js b/api/app/clients/OpenAIClient.js index b87b5f287b..9abf36f588 100644 --- a/api/app/clients/OpenAIClient.js +++ b/api/app/clients/OpenAIClient.js @@ -26,11 +26,11 @@ const { createContextHandlers, } = require('./prompts'); const { encodeAndFormat } = require('~/server/services/Files/images/encode'); +const { isEnabled, sleep } = require('~/server/utils'); const { handleOpenAIErrors } = require('./tools/util'); const spendTokens = require('~/models/spendTokens'); const { createLLM, RunManager } = require('./llm'); const ChatGPTClient = require('./ChatGPTClient'); -const { isEnabled } = require('~/server/utils'); const { summaryBuffer } = require('./memory'); const { runTitleChain } = require('./chains'); const { tokenSplit } = require('./document'); @@ -1079,11 +1079,8 @@ ${convo} ...opts, }); - /* hacky fixes for Mistral AI API: - - Re-orders system message to the top of the messages payload, as not allowed anywhere else - - If there is only one message and it's a system message, change the role to user - */ - if (opts.baseURL.includes('https://api.mistral.ai/v1') && modelOptions.messages) { + /* Re-orders system message to the top of the messages payload, as not allowed anywhere else */ + if (opts.baseURL.includes('api.mistral.ai') && modelOptions.messages) { const { messages } = modelOptions; const systemMessageIndex = messages.findIndex((msg) => msg.role === 'system'); @@ -1094,10 +1091,16 @@ ${convo} } modelOptions.messages = messages; + } - if (messages.length === 1 && messages[0].role === 'system') { - modelOptions.messages[0].role = 'user'; - } + /* If there is only one message and it's a system message, change the role to user */ + if ( + (opts.baseURL.includes('api.mistral.ai') || opts.baseURL.includes('api.perplexity.ai')) && + modelOptions.messages && + modelOptions.messages.length === 1 && + modelOptions.messages[0]?.role === 'system' + ) { + modelOptions.messages[0].role = 'user'; } if (this.options.addParams && typeof this.options.addParams === 'object') { @@ -1151,6 +1154,7 @@ ${convo} } }); + const azureDelay = this.modelOptions.model?.includes('gpt-4') ? 30 : 17; for await (const chunk of stream) { const token = chunk.choices[0]?.delta?.content || ''; intermediateReply += token; @@ -1159,6 +1163,10 @@ ${convo} stream.controller.abort(); break; } + + if (this.azure) { + await sleep(azureDelay); + } } if (!UnexpectedRoleError) { diff --git a/client/src/components/Conversations/Convo.tsx b/client/src/components/Conversations/Convo.tsx index 6e752353ac..3c1ee9f947 100644 --- a/client/src/components/Conversations/Convo.tsx +++ b/client/src/components/Conversations/Convo.tsx @@ -138,6 +138,7 @@ export default function Conversation({ conversation, retainView, toggleNav, isLa onRename={onRename} renameHandler={renameHandler} appendLabel={true} + className="group m-1.5 flex w-full cursor-pointer items-center gap-2 rounded p-2.5 text-sm hover:bg-gray-200 focus-visible:bg-gray-200 focus-visible:outline-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-gray-600 dark:focus-visible:bg-gray-600" /> } + icon={} /> )} diff --git a/client/src/components/Conversations/RenameButton.tsx b/client/src/components/Conversations/RenameButton.tsx index 7c60e23584..5db040ab02 100644 --- a/client/src/components/Conversations/RenameButton.tsx +++ b/client/src/components/Conversations/RenameButton.tsx @@ -7,6 +7,7 @@ interface RenameButtonProps { renameHandler: (e: MouseEvent) => void; onRename: (e: MouseEvent) => void; appendLabel?: boolean; + className?: string; } export default function RenameButton({ @@ -14,15 +15,13 @@ export default function RenameButton({ renameHandler, onRename, appendLabel = false, + className = '', }: RenameButtonProps): ReactElement { const localize = useLocalize(); const handler = renaming ? onRename : renameHandler; return ( - -

- {title || localize('com_ui_new_chat')} -

- - - ); -} diff --git a/client/src/components/Nav/index.ts b/client/src/components/Nav/index.ts index 4a3de60076..625e2918b5 100644 --- a/client/src/components/Nav/index.ts +++ b/client/src/components/Nav/index.ts @@ -2,7 +2,6 @@ export * from './ExportConversation'; export * from './SettingsTabs/'; export { default as ClearConvos } from './ClearConvos'; export { default as Logout } from './Logout'; -export { default as MobileNav } from './MobileNav'; export { default as Nav } from './Nav'; export { default as NavLink } from './NavLink'; export { default as NavLinks } from './NavLinks'; diff --git a/client/src/hooks/Input/useTextarea.ts b/client/src/hooks/Input/useTextarea.ts index e955c522fe..1da901418b 100644 --- a/client/src/hooks/Input/useTextarea.ts +++ b/client/src/hooks/Input/useTextarea.ts @@ -14,6 +14,11 @@ import store from '~/store'; type KeyEvent = KeyboardEvent; +const keyMap = { + 50: '2', + 192: '@', +}; + export default function useTextarea({ textAreaRef, submitButtonRef, @@ -138,24 +143,30 @@ export default function useTextarea({ const handleKeyUp = useCallback( (e: KeyEvent) => { - let isMention = false; - if (e.key === '@' || e.key === '2') { - const text = textAreaRef.current?.value; - isMention = !!(text && text[text.length - 1] === '@'); + let normalizedKey = e.key; + + if (!normalizedKey || normalizedKey === 'Unidentified') { + normalizedKey = keyMap[e.keyCode] || normalizedKey; } - if (isMention) { - const startPos = textAreaRef.current?.selectionStart; - const isAtStart = startPos === 1; - const isPrecededBySpace = - startPos && textAreaRef.current?.value.charAt(startPos - 2) === ' '; - - if (isAtStart || isPrecededBySpace) { - setShowMentionPopover(true); - } else { - setShowMentionPopover(false); - } + if (normalizedKey !== '@' && normalizedKey !== '2') { + return; } + + const text = textAreaRef.current?.value; + if (!(text && text[text.length - 1] === '@')) { + return; + } + + const startPos = textAreaRef.current?.selectionStart; + if (!startPos) { + return; + } + + const isAtStart = startPos === 1; + const isPrecededBySpace = textAreaRef.current?.value.charAt(startPos - 2) === ' '; + + setShowMentionPopover(isAtStart || isPrecededBySpace); }, [textAreaRef, setShowMentionPopover], ); diff --git a/client/src/routes/Root.tsx b/client/src/routes/Root.tsx index 529de11726..4afe07fc88 100644 --- a/client/src/routes/Root.tsx +++ b/client/src/routes/Root.tsx @@ -5,7 +5,7 @@ import { useGetSearchEnabledQuery } from 'librechat-data-provider/react-query'; import type { ContextType } from '~/common'; import { useAuthContext, useAssistantsMap, useFileMap } from '~/hooks'; import { AssistantsMapContext, FileMapContext } from '~/Providers'; -import { Nav, MobileNav } from '~/components/Nav'; +import { Nav } from '~/components/Nav'; import store from '~/store'; export default function Root() { @@ -45,7 +45,6 @@ export default function Root() {