Skip to content

Commit

Permalink
chore: add field to all non-first messages
Browse files Browse the repository at this point in the history
  • Loading branch information
xuzuodong committed Sep 1, 2024
1 parent e7c58c1 commit 53e0865
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const ChatItem: FC<ChatItemProps> = ({
const config = useConfigFromDebugContext()
const {
chatList,
chatListRef,
isResponding,
handleSend,
suggestedQuestions,
Expand Down Expand Up @@ -80,6 +81,8 @@ const ChatItem: FC<ChatItemProps> = ({
query: message,
inputs,
model_config: configData,
is_regenerate: false,
parent_message_id: chatListRef.current.at(-1)?.id || null,
}

if (visionConfig.enabled && files?.length && supportVision)
Expand All @@ -93,7 +96,7 @@ const ChatItem: FC<ChatItemProps> = ({
onGetSuggestedQuestions: (responseItemId, getAbortController) => fetchSuggestedQuestions(appId, responseItemId, getAbortController),
},
)
}, [appId, config, handleSend, inputs, modelAndParameter, textGenerationModelList, visionConfig.enabled])
}, [appId, config, handleSend, inputs, modelAndParameter, textGenerationModelList, visionConfig.enabled, chatListRef])

const { eventEmitter } = useEventEmitterContextContext()
eventEmitter?.useSubscription((v: any) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const DebugWithSingleModel = forwardRef<DebugWithSingleModelRefType, DebugWithSi
const config = useConfigFromDebugContext()
const {
chatList,
chatListRef,
isResponding,
handleSend,
suggestedQuestions,
Expand All @@ -65,7 +66,7 @@ const DebugWithSingleModel = forwardRef<DebugWithSingleModelRefType, DebugWithSi
)
useFormattingChangedSubscription(chatList)

const doSend: OnSend = useCallback((message, files, is_regenerate, last_answer) => {
const doSend: OnSend = useCallback((message, files, is_regenerate = false, last_answer) => {
if (checkCanSend && !checkCanSend())
return
const currentProvider = textGenerationModelList.find(item => item.provider === modelConfig.provider)
Expand All @@ -86,8 +87,8 @@ const DebugWithSingleModel = forwardRef<DebugWithSingleModelRefType, DebugWithSi
query: message,
inputs,
model_config: configData,
is_regenerate: !!is_regenerate,
parent_message_id: last_answer?.id,
is_regenerate,
parent_message_id: last_answer?.id || chatListRef.current.at(-1)?.id || null,
}

if (visionConfig.enabled && files?.length && supportVision)
Expand All @@ -101,7 +102,7 @@ const DebugWithSingleModel = forwardRef<DebugWithSingleModelRefType, DebugWithSi
onGetSuggestedQuestions: (responseItemId, getAbortController) => fetchSuggestedQuestions(appId, responseItemId, getAbortController),
},
)
}, [appId, checkCanSend, completionParams, config, handleSend, inputs, modelConfig, textGenerationModelList, visionConfig.enabled])
}, [chatListRef, appId, checkCanSend, completionParams, config, handleSend, inputs, modelConfig, textGenerationModelList, visionConfig.enabled])

const doRegenerate = useCallback((chatItem: ChatItem) => {
const index = chatList.findIndex(item => item.id === chatItem.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const ChatWrapper = () => {
}, [appParams, currentConversationItem?.introduction, currentConversationId])
const {
chatList,
chatListRef,
handleUpdateChatList,
handleSend,
handleStop,
Expand All @@ -64,13 +65,13 @@ const ChatWrapper = () => {
currentChatInstanceRef.current.handleStop = handleStop
}, [])

const doSend: OnSend = useCallback((message, files, is_regenerate, last_answer) => {
const doSend: OnSend = useCallback((message, files, is_regenerate = false, last_answer) => {
const data: any = {
query: message,
inputs: currentConversationId ? currentConversationItem?.inputs : newConversationInputs,
conversation_id: currentConversationId,
is_regenerate: !!is_regenerate,
parent_message_id: last_answer?.id || null,
is_regenerate,
parent_message_id: last_answer?.id || chatListRef.current.at(-1)?.id || null,
}

if (appConfig?.file_upload?.image.enabled && files?.length)
Expand All @@ -86,6 +87,7 @@ const ChatWrapper = () => {
},
)
}, [
chatListRef,
appConfig,
currentConversationId,
currentConversationItem,
Expand Down
57 changes: 7 additions & 50 deletions web/app/components/base/chat/chat-with-history/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import produce from 'immer'
import type {
Callback,
ChatConfig,
ChatItem,
Feedback,
} from '../types'
import { CONVERSATION_ID_INFO } from '../constants'
import { getPrevChatList } from '../utils'
import {
delConversation,
fetchAppInfo,
Expand All @@ -34,30 +34,10 @@ import type {
AppData,
ConversationItem,
} from '@/models/share'
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
import { useToastContext } from '@/app/components/base/toast'
import { changeLanguage } from '@/i18n/i18next-config'
import { useAppFavicon } from '@/hooks/use-app-favicon'

function appendQAToChatList(chatList: ChatItem[], item: any) {
// we append answer first and then question since will reverse the whole chatList later
chatList.push({
id: item.id,
content: item.answer,
agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
feedback: item.feedback,
isAnswer: true,
citation: item.retriever_resources,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
})
chatList.push({
id: `question-${item.id}`,
content: item.query,
isAnswer: false,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'user') || [],
})
}

export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
const isInstalledApp = useMemo(() => !!installedAppInfo, [installedAppInfo])
const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR(installedAppInfo ? null : 'appInfo', fetchAppInfo)
Expand Down Expand Up @@ -126,35 +106,12 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
const { data: appConversationData, isLoading: appConversationDataLoading, mutate: mutateAppConversationData } = useSWR(['appConversationData', isInstalledApp, appId, false], () => fetchConversations(isInstalledApp, appId, undefined, false, 100))
const { data: appChatListData, isLoading: appChatListDataLoading } = useSWR(chatShouldReloadKey ? ['appChatList', chatShouldReloadKey, isInstalledApp, appId] : null, () => fetchChatList(chatShouldReloadKey, isInstalledApp, appId))

const appPrevChatList = useMemo(() => {
const data = appChatListData?.data || []
const chatList: ChatItem[] = []

if (currentConversationId && data.length) {
let nextMessageId = null
for (const item of data) {
if (item.is_regenerated && !item.parent_message_id) {
appendQAToChatList(chatList, item)
break
}

if (!nextMessageId) {
appendQAToChatList(chatList, item)
if (item.parent_message_id)
nextMessageId = item.parent_message_id
}
else {
if (item.id === nextMessageId) {
appendQAToChatList(chatList, item)
nextMessageId = item.parent_message_id
}
}
}
chatList.reverse()
}

return chatList
}, [appChatListData, currentConversationId])
const appPrevChatList = useMemo(
() => (currentConversationId && appChatListData?.data.length)
? getPrevChatList(appChatListData.data)
: [],
[appChatListData, currentConversationId],
)

const [showNewConversationItemInList, setShowNewConversationItemInList] = useState(false)

Expand Down
1 change: 1 addition & 0 deletions web/app/components/base/chat/chat/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ export const useChat = (

return {
chatList,
chatListRef,
handleUpdateChatList,
conversationId: conversationId.current,
isResponding,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const ChatWrapper = () => {
} as ChatConfig
}, [appParams, currentConversationItem?.introduction, currentConversationId])
const {
chatListRef,
chatList,
handleSend,
handleStop,
Expand All @@ -66,13 +67,13 @@ const ChatWrapper = () => {
currentChatInstanceRef.current.handleStop = handleStop
}, [])

const doSend: OnSend = useCallback((message, files, is_regenerate, last_answer) => {
const doSend: OnSend = useCallback((message, files, is_regenerate = false, last_answer) => {
const data: any = {
query: message,
inputs: currentConversationId ? currentConversationItem?.inputs : newConversationInputs,
conversation_id: currentConversationId,
is_regenerate: !!is_regenerate,
parent_message_id: last_answer?.id || null,
is_regenerate,
parent_message_id: last_answer?.id || chatListRef.current.at(-1)?.id || null,
}

if (appConfig?.file_upload?.image.enabled && files?.length)
Expand All @@ -88,6 +89,7 @@ const ChatWrapper = () => {
},
)
}, [
chatListRef,
appConfig,
currentConversationId,
currentConversationItem,
Expand Down
38 changes: 8 additions & 30 deletions web/app/components/base/chat/embedded-chatbot/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { useLocalStorageState } from 'ahooks'
import produce from 'immer'
import type {
ChatConfig,
ChatItem,
Feedback,
} from '../types'
import { CONVERSATION_ID_INFO } from '../constants'
import { getPrevChatList, getProcessedInputsFromUrlParams } from '../utils'
import {
fetchAppInfo,
fetchAppMeta,
Expand All @@ -28,10 +28,8 @@ import type {
// AppData,
ConversationItem,
} from '@/models/share'
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
import { useToastContext } from '@/app/components/base/toast'
import { changeLanguage } from '@/i18n/i18next-config'
import { getProcessedInputsFromUrlParams } from '@/app/components/base/chat/utils'

export const useEmbeddedChatbot = () => {
const isInstalledApp = false
Expand Down Expand Up @@ -75,32 +73,12 @@ export const useEmbeddedChatbot = () => {
const { data: appConversationData, isLoading: appConversationDataLoading, mutate: mutateAppConversationData } = useSWR(['appConversationData', isInstalledApp, appId, false], () => fetchConversations(isInstalledApp, appId, undefined, false, 100))
const { data: appChatListData, isLoading: appChatListDataLoading } = useSWR(chatShouldReloadKey ? ['appChatList', chatShouldReloadKey, isInstalledApp, appId] : null, () => fetchChatList(chatShouldReloadKey, isInstalledApp, appId))

const appPrevChatList = useMemo(() => {
const data = appChatListData?.data || []
const chatList: ChatItem[] = []

if (currentConversationId && data.length) {
data.forEach((item: any) => {
chatList.push({
id: `question-${item.id}`,
content: item.query,
isAnswer: false,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'user') || [],
})
chatList.push({
id: item.id,
content: item.answer,
agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
feedback: item.feedback,
isAnswer: true,
citation: item.retriever_resources,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
})
})
}

return chatList
}, [appChatListData, currentConversationId])
const appPrevChatList = useMemo(
() => (currentConversationId && appChatListData?.data.length)
? getPrevChatList(appChatListData.data)
: [],
[appChatListData, currentConversationId],
)

const [showNewConversationItemInList, setShowNewConversationItemInList] = useState(false)

Expand Down Expand Up @@ -155,7 +133,7 @@ export const useEmbeddedChatbot = () => {
type: 'text-input',
}
})
}, [appParams])
}, [initInputs, appParams])

useEffect(() => {
// init inputs from url params
Expand Down
60 changes: 59 additions & 1 deletion web/app/components/base/chat/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { addFileInfos, sortAgentSorts } from '../../tools/utils'
import type { ChatItem } from './types'

async function decodeBase64AndDecompress(base64String: string) {
const binaryString = atob(base64String)
const compressedUint8Array = Uint8Array.from(binaryString, char => char.charCodeAt(0))
const decompressedStream = new Response(compressedUint8Array).body.pipeThrough(new DecompressionStream('gzip'))
const decompressedStream = new Response(compressedUint8Array).body?.pipeThrough(new DecompressionStream('gzip'))
const decompressedArrayBuffer = await new Response(decompressedStream).arrayBuffer()
return new TextDecoder().decode(decompressedArrayBuffer)
}
Expand All @@ -15,6 +18,61 @@ function getProcessedInputsFromUrlParams(): Record<string, any> {
return inputs
}

function appendQAToChatList(chatList: ChatItem[], item: any) {
// we append answer first and then question since will reverse the whole chatList later
chatList.push({
id: item.id,
content: item.answer,
agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
feedback: item.feedback,
isAnswer: true,
citation: item.retriever_resources,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
})
chatList.push({
id: `question-${item.id}`,
content: item.query,
isAnswer: false,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'user') || [],
})
}

/**
* Computes the chat list for display.
*
* @param appChatListData - The history chat list data from the backend. This includes all history messages and may contain branches.
* @param currentConversationId - The ID of the current conversation.
* @returns An array of ChatItems representing the latest thread.
*
* Note: The chat list from the backend includes all history messages and may contain branches.
* This function only computes the latest thread from that list.
*/
function getPrevChatList(fetchedMessages: any[]) {
const ret: ChatItem[] = []

let nextMessageId = null
for (const item of fetchedMessages) {
if (item.is_regenerated && !item.parent_message_id) {
appendQAToChatList(ret, item)
break
}

if (!nextMessageId) {
appendQAToChatList(ret, item)
if (item.parent_message_id)
nextMessageId = item.parent_message_id
}
else {
if (item.id === nextMessageId) {
appendQAToChatList(ret, item)
nextMessageId = item.parent_message_id
}
}
}
return ret.reverse()
}

export {
getProcessedInputsFromUrlParams,
getPrevChatList,
}
Loading

0 comments on commit 53e0865

Please sign in to comment.