From fb01216ae2c943e055c03d2566191bc260609ffb Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Thu, 5 Sep 2024 09:54:03 +0700 Subject: [PATCH] fix: disabled UI RAG and tools (#3514) * fix: UI RAG & tools do not support for remote models * chore: update dependencies hooks --- joi/src/core/Tabs/index.tsx | 36 ++++++++++++++++--- joi/src/core/Tabs/styles.scss | 4 +++ web/containers/ModelDropdown/index.tsx | 34 +++++++++++++++++- .../ThreadCenterPanel/ChatInput/index.tsx | 18 ++++++---- web/screens/Thread/ThreadRightPanel/index.tsx | 22 ++++++++++-- 5 files changed, 100 insertions(+), 14 deletions(-) diff --git a/joi/src/core/Tabs/index.tsx b/joi/src/core/Tabs/index.tsx index edec179f1..af004e2ba 100644 --- a/joi/src/core/Tabs/index.tsx +++ b/joi/src/core/Tabs/index.tsx @@ -2,10 +2,18 @@ import React, { ReactNode } from 'react' import * as TabsPrimitive from '@radix-ui/react-tabs' +import { Tooltip } from '../Tooltip' + import './styles.scss' +import { twMerge } from 'tailwind-merge' type TabsProps = { - options: { name: string; value: string }[] + options: { + name: string + value: string + disabled?: boolean + tooltipContent?: string + }[] children: ReactNode defaultValue?: string value: string @@ -15,11 +23,15 @@ type TabsProps = { type TabsContentProps = { value: string children: ReactNode + className?: string } -const TabsContent = ({ value, children }: TabsContentProps) => { +const TabsContent = ({ value, children, className }: TabsContentProps) => { return ( - + {children} ) @@ -40,11 +52,27 @@ const Tabs = ({ > {options.map((option, i) => { - return ( + return option.disabled ? ( + + {option.name} + + } + /> + ) : ( {option.name} diff --git a/joi/src/core/Tabs/styles.scss b/joi/src/core/Tabs/styles.scss index 86948ab5a..a24585b4e 100644 --- a/joi/src/core/Tabs/styles.scss +++ b/joi/src/core/Tabs/styles.scss @@ -21,6 +21,10 @@ &:focus { position: relative; } + &:disabled { + cursor: not-allowed; + opacity: 0.5; + } } &__content { diff --git a/web/containers/ModelDropdown/index.tsx b/web/containers/ModelDropdown/index.tsx index f8920a6dd..d57119b13 100644 --- a/web/containers/ModelDropdown/index.tsx +++ b/web/containers/ModelDropdown/index.tsx @@ -2,7 +2,7 @@ import { useState, useMemo, useEffect, useCallback, useRef } from 'react' import Image from 'next/image' -import { InferenceEngine } from '@janhq/core' +import { InferenceEngine, Model } from '@janhq/core' import { Badge, Button, @@ -28,6 +28,7 @@ import ModelLabel from '@/containers/ModelLabel' import SetupRemoteModel from '@/containers/SetupRemoteModel' +import { useCreateNewThread } from '@/hooks/useCreateNewThread' import useDownloadModel from '@/hooks/useDownloadModel' import { modelDownloadStateAtom } from '@/hooks/useDownloadState' import useRecommendedModel from '@/hooks/useRecommendedModel' @@ -92,6 +93,8 @@ const ModelDropdown = ({ ) const preserveModelSettings = useAtomValue(preserveModelSettingsAtom) + const { updateThreadMetadata } = useCreateNewThread() + useClickOutside(() => !filterOptionsOpen && setOpen(false), null, [ dropdownOptions, toggle, @@ -101,6 +104,13 @@ const ModelDropdown = ({ showEngineListModelAtom ) + const isModelSupportRagAndTools = useCallback((model: Model) => { + return ( + model?.engine === InferenceEngine.openai || + localEngines.includes(model?.engine as InferenceEngine) + ) + }, []) + const filteredDownloadedModels = useMemo( () => configuredModels @@ -161,6 +171,26 @@ const ModelDropdown = ({ setOpen(false) if (activeThread) { + // Change assistand tools based on model support RAG + updateThreadMetadata({ + ...activeThread, + assistants: [ + { + ...activeThread.assistants[0], + tools: [ + { + type: 'retrieval', + enabled: isModelSupportRagAndTools(model as Model), + settings: { + ...(activeThread.assistants[0].tools && + activeThread.assistants[0].tools[0]?.settings), + }, + }, + ], + }, + ], + }) + // Default setting ctx_len for the model for a better onboarding experience // TODO: When Cortex support hardware instructions, we should remove this const defaultContextLength = preserveModelSettings @@ -201,8 +231,10 @@ const ModelDropdown = ({ downloadedModels, activeThread, setSelectedModel, + isModelSupportRagAndTools, setThreadModelParams, updateModelParameter, + updateThreadMetadata, preserveModelSettings, ] ) diff --git a/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx index e3d469a97..141c13fbe 100644 --- a/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/ChatInput/index.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { useEffect, useRef, useState } from 'react' -import { MessageStatus } from '@janhq/core' +import { InferenceEngine, MessageStatus } from '@janhq/core' import { TextArea, Button, Tooltip, useClickOutside, Badge } from '@janhq/joi' import { useAtom, useAtomValue } from 'jotai' @@ -24,12 +24,15 @@ import { useActiveModel } from '@/hooks/useActiveModel' import useSendChatMessage from '@/hooks/useSendChatMessage' +import { localEngines } from '@/utils/modelEngine' + import FileUploadPreview from '../FileUploadPreview' import ImageUploadPreview from '../ImageUploadPreview' import { showRightPanelAtom } from '@/helpers/atoms/App.atom' import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom' +import { selectedModelAtom } from '@/helpers/atoms/Model.atom' import { spellCheckAtom } from '@/helpers/atoms/Setting.atom' import { activeSettingInputBoxAtom, @@ -53,6 +56,7 @@ const ChatInput = () => { activeSettingInputBoxAtom ) const { sendChatMessage } = useSendChatMessage() + const selectedModel = useAtomValue(selectedModelAtom) const activeThreadId = useAtomValue(getActiveThreadIdAtom) const [isWaitingToSend, setIsWaitingToSend] = useAtom(waitingToSendMessage) @@ -124,6 +128,10 @@ const ChatInput = () => { stopInference() } + const isModelSupportRagAndTools = + selectedModel?.engine === InferenceEngine.openai || + localEngines.includes(selectedModel?.engine as InferenceEngine) + /** * Handles the change event of the extension file input element by setting the file name state. * Its to be used to display the extension file name of the selected file. @@ -198,6 +206,7 @@ const ChatInput = () => { } disabled={ + isModelSupportRagAndTools && activeThread?.assistants[0].tools && activeThread?.assistants[0].tools[0]?.enabled } @@ -217,12 +226,7 @@ const ChatInput = () => { )} {activeThread?.assistants[0].tools && activeThread?.assistants[0].tools[0]?.enabled === - false && ( - - Turn on Retrieval in Assistant Settings to use - this feature. - - )} + false && Not supported for this model} ))} diff --git a/web/screens/Thread/ThreadRightPanel/index.tsx b/web/screens/Thread/ThreadRightPanel/index.tsx index e374cb362..c3cb7591d 100644 --- a/web/screens/Thread/ThreadRightPanel/index.tsx +++ b/web/screens/Thread/ThreadRightPanel/index.tsx @@ -1,6 +1,10 @@ import { memo, useCallback, useMemo } from 'react' -import { SettingComponentProps, SliderComponentProps } from '@janhq/core/.' +import { + InferenceEngine, + SettingComponentProps, + SliderComponentProps, +} from '@janhq/core' import { Tabs, TabsContent, @@ -24,6 +28,7 @@ import { useCreateNewThread } from '@/hooks/useCreateNewThread' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' import { getConfigurationsData } from '@/utils/componentSettings' +import { localEngines } from '@/utils/modelEngine' import { toRuntimeParams, toSettingParams } from '@/utils/modelParam' import PromptTemplateSetting from './PromptTemplateSetting' @@ -49,6 +54,10 @@ const ThreadRightPanel = () => { const { updateThreadMetadata } = useCreateNewThread() const experimentalFeature = useAtomValue(experimentalFeatureEnabledAtom) + const isModelSupportRagAndTools = + selectedModel?.engine === InferenceEngine.openai || + localEngines.includes(selectedModel?.engine as InferenceEngine) + const setEngineParamsUpdate = useSetAtom(engineParamsUpdateAtom) const { stopModel } = useActiveModel() const { updateModelParameter } = useUpdateModelParameters() @@ -189,7 +198,16 @@ const ThreadRightPanel = () => { options={[ { name: 'Assistant', value: 'assistant' }, { name: 'Model', value: 'model' }, - ...(experimentalFeature ? [{ name: 'Tools', value: 'tools' }] : []), + ...(experimentalFeature + ? [ + { + name: 'Tools', + value: 'tools', + disabled: !isModelSupportRagAndTools, + tooltipContent: 'Not supported for this model', + }, + ] + : []), ]} value={activeTabThreadRightPanel as string} onValueChange={(value) => setActiveTabThreadRightPanel(value)}