mirror of
http://112.124.100.131/huang.ze/ebiz-dify-ai.git
synced 2025-12-10 03:16:51 +08:00
feat: [frontend] support vision (#1518)
Co-authored-by: Joel <iamjoel007@gmail.com>
This commit is contained in:
@@ -14,7 +14,7 @@ import s from './style.module.css'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import ConfigScene from '@/app/components/share/chatbot/config-scence'
|
||||
import Header from '@/app/components/share/header'
|
||||
import { fetchAppInfo, fetchAppParams, fetchChatList, fetchConversations, fetchSuggestedQuestions, sendChatMessage, stopChatMessageResponding, updateFeedback } from '@/service/share'
|
||||
import { fetchAppInfo, fetchAppParams, fetchChatList, fetchConversations, fetchSuggestedQuestions, generationConversationName, sendChatMessage, stopChatMessageResponding, updateFeedback } from '@/service/share'
|
||||
import type { ConversationItem, SiteInfo } from '@/models/share'
|
||||
import type { PromptConfig, SuggestedQuestionsAfterAnswerConfig } from '@/models/debug'
|
||||
import type { Feedbacktype, IChatItem } from '@/app/components/app/chat/type'
|
||||
@@ -28,6 +28,8 @@ import type { InstalledApp } from '@/models/explore'
|
||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
|
||||
import LogoHeader from '@/app/components/base/logo/logo-embeded-chat-header'
|
||||
import LogoAvatar from '@/app/components/base/logo/logo-embeded-chat-avatar'
|
||||
import type { VisionFile, VisionSettings } from '@/types/app'
|
||||
import { Resolution, TransferMethod } from '@/types/app'
|
||||
|
||||
export type IMainProps = {
|
||||
isInstalledApp?: boolean
|
||||
@@ -184,6 +186,7 @@ const Main: FC<IMainProps> = ({
|
||||
id: `question-${item.id}`,
|
||||
content: item.query,
|
||||
isAnswer: false,
|
||||
message_files: item.message_files,
|
||||
})
|
||||
newChatList.push({
|
||||
id: item.id,
|
||||
@@ -292,7 +295,11 @@ const Main: FC<IMainProps> = ({
|
||||
const isNotNewConversation = allConversations.some(item => item.id === _conversationId)
|
||||
setAllConversationList(allConversations)
|
||||
// fetch new conversation info
|
||||
const { user_input_form, opening_statement: introduction, suggested_questions_after_answer, speech_to_text, sensitive_word_avoidance }: any = appParams
|
||||
const { user_input_form, opening_statement: introduction, suggested_questions_after_answer, speech_to_text, file_upload, sensitive_word_avoidance }: any = appParams
|
||||
setVisionConfig({
|
||||
...file_upload.image,
|
||||
image_file_size_limit: appParams?.system_parameters?.image_file_size_limit,
|
||||
})
|
||||
const prompt_variables = userInputsFormToPromptVariables(user_input_form)
|
||||
if (siteInfo.default_language)
|
||||
changeLanguage(siteInfo.default_language)
|
||||
@@ -371,24 +378,48 @@ const Main: FC<IMainProps> = ({
|
||||
const [messageTaskId, setMessageTaskId] = useState('')
|
||||
const [hasStopResponded, setHasStopResponded, getHasStopResponded] = useGetState(false)
|
||||
const [shouldReload, setShouldReload] = useState(false)
|
||||
const [visionConfig, setVisionConfig] = useState<VisionSettings>({
|
||||
enabled: false,
|
||||
number_limits: 2,
|
||||
detail: Resolution.low,
|
||||
transfer_methods: [TransferMethod.local_file],
|
||||
})
|
||||
|
||||
const handleSend = async (message: string) => {
|
||||
const handleSend = async (message: string, files?: VisionFile[]) => {
|
||||
if (isResponsing) {
|
||||
notify({ type: 'info', message: t('appDebug.errorMessage.waitForResponse') })
|
||||
return
|
||||
}
|
||||
const data = {
|
||||
|
||||
if (files?.find(item => item.transfer_method === TransferMethod.local_file && !item.upload_file_id)) {
|
||||
notify({ type: 'info', message: t('appDebug.errorMessage.waitForImgUpload') })
|
||||
return false
|
||||
}
|
||||
const data: Record<string, any> = {
|
||||
inputs: currInputs,
|
||||
query: message,
|
||||
conversation_id: isNewConversation ? null : currConversationId,
|
||||
}
|
||||
|
||||
if (visionConfig.enabled && files && files?.length > 0) {
|
||||
data.files = files.map((item) => {
|
||||
if (item.transfer_method === TransferMethod.local_file) {
|
||||
return {
|
||||
...item,
|
||||
url: '',
|
||||
}
|
||||
}
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
// qustion
|
||||
const questionId = `question-${Date.now()}`
|
||||
const questionItem = {
|
||||
id: questionId,
|
||||
content: message,
|
||||
isAnswer: false,
|
||||
message_files: files,
|
||||
}
|
||||
|
||||
const placeholderAnswerId = `answer-placeholder-${Date.now()}`
|
||||
@@ -436,13 +467,16 @@ const Main: FC<IMainProps> = ({
|
||||
setChatList(newListWithAnswer)
|
||||
},
|
||||
async onCompleted(hasError?: boolean) {
|
||||
setResponsingFalse()
|
||||
if (hasError)
|
||||
return
|
||||
|
||||
if (getConversationIdChangeBecauseOfNew()) {
|
||||
const { data: allConversations }: any = await fetchAllConversations()
|
||||
setAllConversationList(allConversations)
|
||||
const newItem: any = await generationConversationName(isInstalledApp, installedAppInfo?.id, allConversations[0].id)
|
||||
const newAllConversations = produce(allConversations, (draft: any) => {
|
||||
draft[0].name = newItem.name
|
||||
})
|
||||
setAllConversationList(newAllConversations as any)
|
||||
noticeUpdateList()
|
||||
}
|
||||
setConversationIdChangeBecauseOfNew(false)
|
||||
@@ -454,6 +488,7 @@ const Main: FC<IMainProps> = ({
|
||||
setSuggestQuestions(data)
|
||||
setIsShowSuggestion(true)
|
||||
}
|
||||
setResponsingFalse()
|
||||
},
|
||||
onMessageReplace: (messageReplace) => {
|
||||
setChatList(produce(
|
||||
@@ -581,6 +616,7 @@ const Main: FC<IMainProps> = ({
|
||||
displayScene='web'
|
||||
isShowSpeechToText={speechToTextConfig?.enabled}
|
||||
answerIcon={<LogoAvatar className='relative shrink-0' />}
|
||||
visionConfig={visionConfig}
|
||||
/>
|
||||
</div>
|
||||
</div>)
|
||||
|
||||
Reference in New Issue
Block a user