feat: Add user variable processing function to chat history (#22863)

This commit is contained in:
croatialu
2025-07-24 10:06:49 +08:00
committed by GitHub
parent ef51678c73
commit d1572f47a0
5 changed files with 37 additions and 4 deletions

View File

@@ -23,6 +23,7 @@ import SuggestedQuestions from '@/app/components/base/chat/chat/answer/suggested
import { Markdown } from '@/app/components/base/markdown' import { Markdown } from '@/app/components/base/markdown'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import type { FileEntity } from '../../file-uploader/types' import type { FileEntity } from '../../file-uploader/types'
import Avatar from '../../avatar'
const ChatWrapper = () => { const ChatWrapper = () => {
const { const {
@@ -48,6 +49,7 @@ const ChatWrapper = () => {
setClearChatList, setClearChatList,
setIsResponding, setIsResponding,
allInputsHidden, allInputsHidden,
initUserVariables,
} = useChatWithHistoryContext() } = useChatWithHistoryContext()
const appConfig = useMemo(() => { const appConfig = useMemo(() => {
const config = appParams || {} const config = appParams || {}
@@ -119,7 +121,6 @@ const ChatWrapper = () => {
useEffect(() => { useEffect(() => {
if (currentChatInstanceRef.current) if (currentChatInstanceRef.current)
currentChatInstanceRef.current.handleStop = handleStop currentChatInstanceRef.current.handleStop = handleStop
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])
useEffect(() => { useEffect(() => {
@@ -238,7 +239,7 @@ const ChatWrapper = () => {
className='h-full overflow-hidden bg-chatbot-bg' className='h-full overflow-hidden bg-chatbot-bg'
> >
<Chat <Chat
appData={appData} appData={appData ?? undefined}
config={appConfig} config={appConfig}
chatList={messageList} chatList={messageList}
isResponding={respondingState} isResponding={respondingState}
@@ -266,6 +267,14 @@ const ChatWrapper = () => {
inputDisabled={inputDisabled} inputDisabled={inputDisabled}
isMobile={isMobile} isMobile={isMobile}
sidebarCollapseState={sidebarCollapseState} sidebarCollapseState={sidebarCollapseState}
questionIcon={
initUserVariables?.avatar_url
? <Avatar
avatar={initUserVariables.avatar_url}
name={initUserVariables.name || 'user'}
size={40}
/> : undefined
}
/> />
</div> </div>
) )

View File

@@ -56,6 +56,10 @@ export type ChatWithHistoryContextValue = {
currentConversationInputs: Record<string, any> | null, currentConversationInputs: Record<string, any> | null,
setCurrentConversationInputs: (v: Record<string, any>) => void, setCurrentConversationInputs: (v: Record<string, any>) => void,
allInputsHidden: boolean, allInputsHidden: boolean,
initUserVariables?: {
name?: string
avatar_url?: string
}
} }
export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>({ export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>({
@@ -90,5 +94,6 @@ export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>
currentConversationInputs: {}, currentConversationInputs: {},
setCurrentConversationInputs: noop, setCurrentConversationInputs: noop,
allInputsHidden: false, allInputsHidden: false,
initUserVariables: {},
}) })
export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext) export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext)

View File

@@ -16,7 +16,7 @@ import type {
Feedback, Feedback,
} from '../types' } from '../types'
import { CONVERSATION_ID_INFO } from '../constants' import { CONVERSATION_ID_INFO } from '../constants'
import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams, getRawInputsFromUrlParams } from '../utils' import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams, getRawInputsFromUrlParams, getRawUserVariablesFromUrlParams } from '../utils'
import { addFileInfos, sortAgentSorts } from '../../../tools/utils' import { addFileInfos, sortAgentSorts } from '../../../tools/utils'
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
import { import {
@@ -181,6 +181,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
const newConversationInputsRef = useRef<Record<string, any>>({}) const newConversationInputsRef = useRef<Record<string, any>>({})
const [newConversationInputs, setNewConversationInputs] = useState<Record<string, any>>({}) const [newConversationInputs, setNewConversationInputs] = useState<Record<string, any>>({})
const [initInputs, setInitInputs] = useState<Record<string, any>>({}) const [initInputs, setInitInputs] = useState<Record<string, any>>({})
const [initUserVariables, setInitUserVariables] = useState<Record<string, any>>({})
const handleNewConversationInputsChange = useCallback((newInputs: Record<string, any>) => { const handleNewConversationInputsChange = useCallback((newInputs: Record<string, any>) => {
newConversationInputsRef.current = newInputs newConversationInputsRef.current = newInputs
setNewConversationInputs(newInputs) setNewConversationInputs(newInputs)
@@ -249,7 +250,9 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
// init inputs from url params // init inputs from url params
(async () => { (async () => {
const inputs = await getRawInputsFromUrlParams() const inputs = await getRawInputsFromUrlParams()
const userVariables = await getRawUserVariablesFromUrlParams()
setInitInputs(inputs) setInitInputs(inputs)
setInitUserVariables(userVariables)
})() })()
}, []) }, [])
@@ -520,5 +523,6 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
currentConversationInputs, currentConversationInputs,
setCurrentConversationInputs, setCurrentConversationInputs,
allInputsHidden, allInputsHidden,
initUserVariables,
} }
} }

View File

@@ -142,6 +142,7 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
currentConversationInputs, currentConversationInputs,
setCurrentConversationInputs, setCurrentConversationInputs,
allInputsHidden, allInputsHidden,
initUserVariables,
} = useChatWithHistory(installedAppInfo) } = useChatWithHistory(installedAppInfo)
return ( return (
@@ -184,6 +185,7 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
currentConversationInputs, currentConversationInputs,
setCurrentConversationInputs, setCurrentConversationInputs,
allInputsHidden, allInputsHidden,
initUserVariables,
}}> }}>
<ChatWithHistory className={className} /> <ChatWithHistory className={className} />
</ChatWithHistoryContext.Provider> </ChatWithHistoryContext.Provider>

View File

@@ -20,7 +20,8 @@ async function getRawInputsFromUrlParams(): Promise<Record<string, any>> {
const inputs: Record<string, any> = {} const inputs: Record<string, any> = {}
const entriesArray = Array.from(urlParams.entries()) const entriesArray = Array.from(urlParams.entries())
entriesArray.forEach(([key, value]) => { entriesArray.forEach(([key, value]) => {
if (!key.startsWith('sys.')) const prefixArray = ['sys.', 'user.']
if (!prefixArray.some(prefix => key.startsWith(prefix)))
inputs[key] = decodeURIComponent(value) inputs[key] = decodeURIComponent(value)
}) })
return inputs return inputs
@@ -66,6 +67,17 @@ async function getProcessedUserVariablesFromUrlParams(): Promise<Record<string,
return userVariables return userVariables
} }
async function getRawUserVariablesFromUrlParams(): Promise<Record<string, any>> {
const urlParams = new URLSearchParams(window.location.search)
const userVariables: Record<string, any> = {}
const entriesArray = Array.from(urlParams.entries())
entriesArray.forEach(([key, value]) => {
if (key.startsWith('user.'))
userVariables[key.slice(5)] = decodeURIComponent(value)
})
return userVariables
}
function isValidGeneratedAnswer(item?: ChatItem | ChatItemInTree): boolean { function isValidGeneratedAnswer(item?: ChatItem | ChatItemInTree): boolean {
return !!item && item.isAnswer && !item.id.startsWith('answer-placeholder-') && !item.isOpeningStatement return !!item && item.isAnswer && !item.id.startsWith('answer-placeholder-') && !item.isOpeningStatement
} }
@@ -213,6 +225,7 @@ export {
getProcessedInputsFromUrlParams, getProcessedInputsFromUrlParams,
getProcessedSystemVariablesFromUrlParams, getProcessedSystemVariablesFromUrlParams,
getProcessedUserVariablesFromUrlParams, getProcessedUserVariablesFromUrlParams,
getRawUserVariablesFromUrlParams,
isValidGeneratedAnswer, isValidGeneratedAnswer,
getLastAnswer, getLastAnswer,
buildChatItemTree, buildChatItemTree,