diff --git a/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx b/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx index ad4c06bb..219e30f3 100644 --- a/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx +++ b/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx @@ -74,6 +74,7 @@ const ChatItem: FC = ({ handleRestart, } = useChat( config, + userProfile.id, { inputs, inputsForm, diff --git a/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx b/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx index d439b009..e9d8ba59 100644 --- a/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx +++ b/dify_1.9.0/web/app/components/app/configuration/debug/debug-with-single-model/index.tsx @@ -80,6 +80,7 @@ const DebugWithSingleModel = ( handleAnnotationRemoved, } = useChat( config, + userProfile.id, { inputs, inputsForm, diff --git a/dify_1.9.0/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx b/dify_1.9.0/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx index cc5e46de..7f3d99c0 100644 --- a/dify_1.9.0/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx +++ b/dify_1.9.0/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx @@ -51,6 +51,7 @@ const ChatWrapper = () => { setIsResponding, allInputsHidden, initUserVariables, + userIdFromQuery, } = useChatWithHistoryContext() // Semantic variable for better code readability @@ -76,17 +77,24 @@ const ChatWrapper = () => { handleStop, isResponding: respondingState, suggestedQuestions, - } = useChat( - appConfig, - { - inputs: (isHistoryConversation ? currentConversationInputs : newConversationInputs) as any, - inputsForm: inputsForms, + } = useChat({ + appData: appData!, + appParams: appData?.site.default_language ? { ...appParams, language: appData?.site.default_language } : appParams, + isInstalledApp, + appId, + conversationId: currentConversationId, + inputs: currentConversationInputs, + promptVariables: allInputsHidden ? currentConversationInputs : {}, + prevChatList: appPrevChatTree, + onNewConversation: handleNewConversationCompleted, + onConversationIdChange: (id) => { + handleNewConversationCompleted(id) }, - appPrevChatTree, - taskId => stopChatMessageResponding('', taskId, isInstalledApp, appId), - clearChatList, - setClearChatList, - ) + onRespondingChanged: setIsResponding, + onClearChatList: clearChatList, + onClearChatListFinished: () => setClearChatList(false), + user: userIdFromQuery || initUserVariables?.user_id, + }) const inputsFormValue = isHistoryConversation ? currentConversationInputs : newConversationInputsRef?.current const inputDisabled = useMemo(() => { if (allInputsHidden) diff --git a/dify_1.9.0/web/app/components/base/chat/chat-with-history/context.tsx b/dify_1.9.0/web/app/components/base/chat/chat-with-history/context.tsx index 03a03991..b73750c4 100644 --- a/dify_1.9.0/web/app/components/base/chat/chat-with-history/context.tsx +++ b/dify_1.9.0/web/app/components/base/chat/chat-with-history/context.tsx @@ -60,6 +60,7 @@ export type ChatWithHistoryContextValue = { name?: string avatar_url?: string } + userIdFromQuery?: string } export const ChatWithHistoryContext = createContext({ @@ -95,5 +96,6 @@ export const ChatWithHistoryContext = createContext setCurrentConversationInputs: noop, allInputsHidden: false, initUserVariables: {}, + userIdFromQuery: '', }) export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext) diff --git a/dify_1.9.0/web/app/components/base/chat/chat-with-history/hooks.tsx b/dify_1.9.0/web/app/components/base/chat/chat-with-history/hooks.tsx index fb3e1bb8..35e93534 100644 --- a/dify_1.9.0/web/app/components/base/chat/chat-with-history/hooks.tsx +++ b/dify_1.9.0/web/app/components/base/chat/chat-with-history/hooks.tsx @@ -16,7 +16,7 @@ import type { Feedback, } from '../types' import { CONVERSATION_ID_INFO } from '../constants' -import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams, getRawInputsFromUrlParams, getRawUserVariablesFromUrlParams } from '../utils' +import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams, getRawInputsFromUrlParams, getRawUserVariablesFromUrlParams, getUserIdFromUrlParams } from '../utils' import { addFileInfos, sortAgentSorts } from '../../../tools/utils' import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' import { @@ -68,7 +68,7 @@ function getFormattedChatList(messages: any[]) { return newChatList } -export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { +export const useChatWithHistory = (installedAppInfo?: InstalledApp, user_id?: string) => { const isInstalledApp = useMemo(() => !!installedAppInfo, [installedAppInfo]) const appInfo = useWebAppStore(s => s.appInfo) const appParams = useWebAppStore(s => s.appParams) @@ -108,11 +108,18 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { const appId = useMemo(() => appData?.app_id, [appData]) const [userId, setUserId] = useState() + const [userIdFromQuery, setUserIdFromQuery] = useState('') useEffect(() => { - getProcessedSystemVariablesFromUrlParams().then(({ user_id }) => { + if (user_id) setUserId(user_id) - }) - }, []) + else + getProcessedSystemVariablesFromUrlParams().then(({ user_id }) => { + setUserId(user_id) + }) + // Get userid from URL query parameter + const queryUserId = getUserIdFromUrlParams() + setUserIdFromQuery(queryUserId) + }, [user_id]) useEffect(() => { const setLocaleFromProps = async () => { @@ -570,5 +577,6 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { setCurrentConversationInputs, allInputsHidden, initUserVariables, + userIdFromQuery, } } diff --git a/dify_1.9.0/web/app/components/base/chat/chat-with-history/index.tsx b/dify_1.9.0/web/app/components/base/chat/chat-with-history/index.tsx index 464e30a8..5ef8431d 100644 --- a/dify_1.9.0/web/app/components/base/chat/chat-with-history/index.tsx +++ b/dify_1.9.0/web/app/components/base/chat/chat-with-history/index.tsx @@ -22,6 +22,7 @@ import { checkOrSetAccessToken } from '@/app/components/share/utils' import AppUnavailable from '@/app/components/base/app-unavailable' import cn from '@/utils/classnames' import useDocumentTitle from '@/hooks/use-document-title' +import { useSearchParams } from 'next/navigation' type ChatWithHistoryProps = { className?: string @@ -40,6 +41,8 @@ const ChatWithHistory: FC = ({ const isSidebarCollapsed = sidebarCollapseState const customConfig = appData?.custom_config const site = appData?.site + const searchParams = useSearchParams() + const userid = searchParams.get('userid') const [showSidePanel, setShowSidePanel] = useState(false) @@ -109,6 +112,8 @@ const ChatWithHistoryWrap: FC = ({ const media = useBreakpoints() const isMobile = media === MediaType.mobile const themeBuilder = useThemeContext() + const searchParams = useSearchParams() + const userid = searchParams.get('userid') const { appData, @@ -148,7 +153,8 @@ const ChatWithHistoryWrap: FC = ({ setCurrentConversationInputs, allInputsHidden, initUserVariables, - } = useChatWithHistory(installedAppInfo) + userIdFromQuery, + } = useChatWithHistory(installedAppInfo, userid) return ( = ({ setCurrentConversationInputs, allInputsHidden, initUserVariables, + userIdFromQuery, }}> diff --git a/dify_1.9.0/web/app/components/base/chat/chat/hooks.ts b/dify_1.9.0/web/app/components/base/chat/chat/hooks.ts index 665e7e8b..5bc61889 100644 --- a/dify_1.9.0/web/app/components/base/chat/chat/hooks.ts +++ b/dify_1.9.0/web/app/components/base/chat/chat/hooks.ts @@ -46,6 +46,7 @@ type SendCallback = { export const useChat = ( config?: ChatConfig, + user?: string, formSettings?: { inputs: Inputs inputsForm: InputForm[] @@ -276,6 +277,7 @@ export const useChat = ( const bodyParams = { response_mode: 'streaming', conversation_id: conversationId.current, + user: user || '', files: getProcessedFiles(files || []), query, inputs: getProcessedInputs(inputs || {}, formSettings?.inputsForm || []), diff --git a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx index 14a291e9..45443256 100644 --- a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx +++ b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx @@ -51,6 +51,7 @@ const ChatWrapper = () => { setIsResponding, allInputsHidden, initUserVariables, + userIdFromQuery, } = useEmbeddedChatbotContext() const appConfig = useMemo(() => { const config = appParams || {} @@ -74,6 +75,7 @@ const ChatWrapper = () => { suggestedQuestions, } = useChat( appConfig, + userIdFromQuery || initUserVariables?.user_id, { inputs: (currentConversationId ? currentConversationInputs : newConversationInputs) as any, inputsForm: inputsForms, diff --git a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/context.tsx b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/context.tsx index 544da253..ef0b9dfb 100644 --- a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/context.tsx +++ b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/context.tsx @@ -56,6 +56,7 @@ export type EmbeddedChatbotContextValue = { name?: string avatar_url?: string } + userIdFromQuery?: string } export const EmbeddedChatbotContext = createContext({ @@ -86,5 +87,6 @@ export const EmbeddedChatbotContext = createContext setCurrentConversationInputs: noop, allInputsHidden: false, initUserVariables: {}, + userIdFromQuery: '', }) export const useEmbeddedChatbotContext = () => useContext(EmbeddedChatbotContext) diff --git a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/hooks.tsx b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/hooks.tsx index 14a32860..ec26d3bf 100644 --- a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/hooks.tsx +++ b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/hooks.tsx @@ -15,7 +15,7 @@ import type { Feedback, } from '../types' import { CONVERSATION_ID_INFO } from '../constants' -import { buildChatItemTree, getProcessedInputsFromUrlParams, getProcessedSystemVariablesFromUrlParams, getProcessedUserVariablesFromUrlParams } from '../utils' +import { buildChatItemTree, getProcessedInputsFromUrlParams, getProcessedSystemVariablesFromUrlParams, getProcessedUserVariablesFromUrlParams, getUserIdFromUrlParams } from '../utils' import { getProcessedFilesFromResponse } from '../../file-uploader/utils' import { fetchAppInfo, @@ -82,11 +82,15 @@ export const useEmbeddedChatbot = () => { const [userId, setUserId] = useState() const [conversationId, setConversationId] = useState() + const [userIdFromQuery, setUserIdFromQuery] = useState('') useEffect(() => { getProcessedSystemVariablesFromUrlParams().then(({ user_id, conversation_id }) => { setUserId(user_id) setConversationId(conversation_id) }) + // Get userid from URL query parameter + const queryUserId = getUserIdFromUrlParams() + setUserIdFromQuery(queryUserId) }, []) useEffect(() => { @@ -436,5 +440,6 @@ export const useEmbeddedChatbot = () => { setCurrentConversationInputs, allInputsHidden, initUserVariables, + userIdFromQuery, } } diff --git a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/index.tsx b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/index.tsx index e23b5ec3..cea4ec35 100644 --- a/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/index.tsx +++ b/dify_1.9.0/web/app/components/base/chat/embedded-chatbot/index.tsx @@ -114,6 +114,7 @@ const EmbeddedChatbotWrapper = () => { setCurrentConversationInputs, allInputsHidden, initUserVariables, + userIdFromQuery, } = useEmbeddedChatbot() return { setCurrentConversationInputs, allInputsHidden, initUserVariables, + userIdFromQuery, }}> diff --git a/dify_1.9.0/web/app/components/base/chat/utils.ts b/dify_1.9.0/web/app/components/base/chat/utils.ts index 34df617a..fdfeebc2 100644 --- a/dify_1.9.0/web/app/components/base/chat/utils.ts +++ b/dify_1.9.0/web/app/components/base/chat/utils.ts @@ -88,6 +88,12 @@ async function getRawUserVariablesFromUrlParams(): Promise> return userVariables } +function getUserIdFromUrlParams(): string { + const urlParams = new URLSearchParams(window.location.search) + const userId = urlParams.get('userid') + return userId ? decodeURIComponent(userId) : '' +} + function isValidGeneratedAnswer(item?: ChatItem | ChatItemInTree): boolean { return !!item && item.isAnswer && !item.id.startsWith('answer-placeholder-') && !item.isOpeningStatement } @@ -236,6 +242,7 @@ export { getProcessedSystemVariablesFromUrlParams, getProcessedUserVariablesFromUrlParams, getRawUserVariablesFromUrlParams, + getUserIdFromUrlParams, isValidGeneratedAnswer, getLastAnswer, buildChatItemTree, diff --git a/dify_1.9.0/web/app/components/share/text-generation/index.tsx b/dify_1.9.0/web/app/components/share/text-generation/index.tsx index f62332e5..27b71bfe 100644 --- a/dify_1.9.0/web/app/components/share/text-generation/index.tsx +++ b/dify_1.9.0/web/app/components/share/text-generation/index.tsx @@ -41,6 +41,7 @@ import { AccessMode } from '@/models/access-control' import { useGlobalPublicStore } from '@/context/global-public-context' import useDocumentTitle from '@/hooks/use-document-title' import { useWebAppStore } from '@/context/web-app-context' +import { getUserIdFromUrlParams } from '@/app/components/base/chat/utils' const GROUP_SIZE = 5 // to avoid RPM(Request per minute) limit. The group task finished then the next group. enum TaskStatus { @@ -125,6 +126,13 @@ const TextGeneration: FC = ({ transfer_methods: [TransferMethod.local_file], }) const [completionFiles, setCompletionFiles] = useState([]) + const [userIdFromQuery, setUserIdFromQuery] = useState('') + + useEffect(() => { + // Get userid from URL query parameter + const queryUserId = getUserIdFromUrlParams() + setUserIdFromQuery(queryUserId) + }, []) const handleSend = () => { setIsCallBatchAPI(false) @@ -433,6 +441,7 @@ const TextGeneration: FC = ({ isShowTextToSpeech={!!textToSpeechConfig?.enabled} siteInfo={siteInfo} onRunStart={() => setResultExisted(true)} + userIdFromQuery={userIdFromQuery} />) const renderBatchRes = () => { diff --git a/dify_1.9.0/web/app/components/share/text-generation/result/index.tsx b/dify_1.9.0/web/app/components/share/text-generation/result/index.tsx index a7eb7f75..2a4eef1e 100644 --- a/dify_1.9.0/web/app/components/share/text-generation/result/index.tsx +++ b/dify_1.9.0/web/app/components/share/text-generation/result/index.tsx @@ -46,6 +46,7 @@ export type IResultProps = { completionFiles: VisionFile[] siteInfo: SiteInfo | null onRunStart: () => void + userIdFromQuery?: string } const Result: FC = ({ @@ -71,6 +72,7 @@ const Result: FC = ({ completionFiles, siteInfo, onRunStart, + userIdFromQuery, }) => { const [isResponding, { setTrue: setRespondingTrue, setFalse: setRespondingFalse }] = useBoolean(false) useEffect(() => { @@ -162,6 +164,7 @@ const Result: FC = ({ const data: Record = { inputs: formatBooleanInputs(promptConfig?.prompt_variables, inputs), + user: userIdFromQuery || '', } if (visionConfig.enabled && completionFiles && completionFiles?.length > 0) { data.files = completionFiles.map((item) => { diff --git a/dify_1.9.0/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx b/dify_1.9.0/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx index 1a97357d..523e9313 100644 --- a/dify_1.9.0/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx +++ b/dify_1.9.0/web/app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx @@ -23,6 +23,7 @@ import { getLastAnswer, isValidGeneratedAnswer } from '@/app/components/base/cha import type { FileEntity } from '@/app/components/base/file-uploader/types' import { useEventEmitterContextContext } from '@/context/event-emitter' import { EVENT_WORKFLOW_STOP } from '@/app/components/workflow/variable-inspect/types' +import { useAppContext } from '@/context/app-context' type ChatWrapperProps = { showConversationVariableModal: boolean @@ -42,6 +43,7 @@ const ChatWrapper = ( ref: React.RefObject; }, ) => { + const { userProfile } = useAppContext() const nodes = useNodes() const startNode = nodes.find(node => node.data.type === BlockEnum.Start) const startVariables = startNode?.data.variables @@ -89,6 +91,7 @@ const ChatWrapper = ( setTargetMessageId, } = useChat( config, + userProfile.id, { inputs, inputsForm: (startVariables || []) as any,