dify自带聊天页实现uid参数参数
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# base image
|
||||
FROM node:22-alpine3.21 AS base
|
||||
FROM fiof1uwu2mjtuh.xuanyuan.run/node:22-alpine3.21 AS base
|
||||
LABEL maintainer="takatost@gmail.com"
|
||||
|
||||
# if you located in China, you can use aliyun mirror to speed up
|
||||
|
||||
@@ -74,6 +74,7 @@ const ChatItem: FC<ChatItemProps> = ({
|
||||
handleRestart,
|
||||
} = useChat(
|
||||
config,
|
||||
userProfile.id,
|
||||
{
|
||||
inputs,
|
||||
inputsForm,
|
||||
|
||||
@@ -80,6 +80,7 @@ const DebugWithSingleModel = (
|
||||
handleAnnotationRemoved,
|
||||
} = useChat(
|
||||
config,
|
||||
userProfile.id,
|
||||
{
|
||||
inputs,
|
||||
inputsForm,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -60,6 +60,7 @@ export type ChatWithHistoryContextValue = {
|
||||
name?: string
|
||||
avatar_url?: string
|
||||
}
|
||||
userIdFromQuery?: string
|
||||
}
|
||||
|
||||
export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>({
|
||||
@@ -95,5 +96,6 @@ export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>
|
||||
setCurrentConversationInputs: noop,
|
||||
allInputsHidden: false,
|
||||
initUserVariables: {},
|
||||
userIdFromQuery: '',
|
||||
})
|
||||
export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext)
|
||||
|
||||
@@ -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<string>()
|
||||
const [userIdFromQuery, setUserIdFromQuery] = useState<string>('')
|
||||
useEffect(() => {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ChatWithHistoryProps> = ({
|
||||
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<ChatWithHistoryWrapProps> = ({
|
||||
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<ChatWithHistoryWrapProps> = ({
|
||||
setCurrentConversationInputs,
|
||||
allInputsHidden,
|
||||
initUserVariables,
|
||||
} = useChatWithHistory(installedAppInfo)
|
||||
userIdFromQuery,
|
||||
} = useChatWithHistory(installedAppInfo, userid)
|
||||
|
||||
return (
|
||||
<ChatWithHistoryContext.Provider value={{
|
||||
@@ -191,6 +197,7 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
|
||||
setCurrentConversationInputs,
|
||||
allInputsHidden,
|
||||
initUserVariables,
|
||||
userIdFromQuery,
|
||||
}}>
|
||||
<ChatWithHistory className={className} />
|
||||
</ChatWithHistoryContext.Provider>
|
||||
|
||||
@@ -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 || []),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -56,6 +56,7 @@ export type EmbeddedChatbotContextValue = {
|
||||
name?: string
|
||||
avatar_url?: string
|
||||
}
|
||||
userIdFromQuery?: string
|
||||
}
|
||||
|
||||
export const EmbeddedChatbotContext = createContext<EmbeddedChatbotContextValue>({
|
||||
@@ -86,5 +87,6 @@ export const EmbeddedChatbotContext = createContext<EmbeddedChatbotContextValue>
|
||||
setCurrentConversationInputs: noop,
|
||||
allInputsHidden: false,
|
||||
initUserVariables: {},
|
||||
userIdFromQuery: '',
|
||||
})
|
||||
export const useEmbeddedChatbotContext = () => useContext(EmbeddedChatbotContext)
|
||||
|
||||
@@ -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<string>()
|
||||
const [conversationId, setConversationId] = useState<string>()
|
||||
const [userIdFromQuery, setUserIdFromQuery] = useState<string>('')
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ const EmbeddedChatbotWrapper = () => {
|
||||
setCurrentConversationInputs,
|
||||
allInputsHidden,
|
||||
initUserVariables,
|
||||
userIdFromQuery,
|
||||
} = useEmbeddedChatbot()
|
||||
|
||||
return <EmbeddedChatbotContext.Provider value={{
|
||||
@@ -169,6 +170,7 @@ const EmbeddedChatbotWrapper = () => {
|
||||
setCurrentConversationInputs,
|
||||
allInputsHidden,
|
||||
initUserVariables,
|
||||
userIdFromQuery,
|
||||
}}>
|
||||
<Chatbot />
|
||||
</EmbeddedChatbotContext.Provider>
|
||||
|
||||
@@ -88,6 +88,12 @@ async function getRawUserVariablesFromUrlParams(): Promise<Record<string, any>>
|
||||
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,
|
||||
|
||||
@@ -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<IMainProps> = ({
|
||||
transfer_methods: [TransferMethod.local_file],
|
||||
})
|
||||
const [completionFiles, setCompletionFiles] = useState<VisionFile[]>([])
|
||||
const [userIdFromQuery, setUserIdFromQuery] = useState<string>('')
|
||||
|
||||
useEffect(() => {
|
||||
// Get userid from URL query parameter
|
||||
const queryUserId = getUserIdFromUrlParams()
|
||||
setUserIdFromQuery(queryUserId)
|
||||
}, [])
|
||||
|
||||
const handleSend = () => {
|
||||
setIsCallBatchAPI(false)
|
||||
@@ -433,6 +441,7 @@ const TextGeneration: FC<IMainProps> = ({
|
||||
isShowTextToSpeech={!!textToSpeechConfig?.enabled}
|
||||
siteInfo={siteInfo}
|
||||
onRunStart={() => setResultExisted(true)}
|
||||
userIdFromQuery={userIdFromQuery}
|
||||
/>)
|
||||
|
||||
const renderBatchRes = () => {
|
||||
|
||||
@@ -46,6 +46,7 @@ export type IResultProps = {
|
||||
completionFiles: VisionFile[]
|
||||
siteInfo: SiteInfo | null
|
||||
onRunStart: () => void
|
||||
userIdFromQuery?: string
|
||||
}
|
||||
|
||||
const Result: FC<IResultProps> = ({
|
||||
@@ -71,6 +72,7 @@ const Result: FC<IResultProps> = ({
|
||||
completionFiles,
|
||||
siteInfo,
|
||||
onRunStart,
|
||||
userIdFromQuery,
|
||||
}) => {
|
||||
const [isResponding, { setTrue: setRespondingTrue, setFalse: setRespondingFalse }] = useBoolean(false)
|
||||
useEffect(() => {
|
||||
@@ -162,6 +164,7 @@ const Result: FC<IResultProps> = ({
|
||||
|
||||
const data: Record<string, any> = {
|
||||
inputs: formatBooleanInputs(promptConfig?.prompt_variables, inputs),
|
||||
user: userIdFromQuery || '',
|
||||
}
|
||||
if (visionConfig.enabled && completionFiles && completionFiles?.length > 0) {
|
||||
data.files = completionFiles.map((item) => {
|
||||
|
||||
@@ -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<ChatWrapperRefType>;
|
||||
},
|
||||
) => {
|
||||
const { userProfile } = useAppContext()
|
||||
const nodes = useNodes<StartNodeType>()
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user