mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-13 20:16:00 +08:00
feat: improve embedding sys.user_id and conversion id info usage (#18035)
This commit is contained in:
parent
358fd28c28
commit
44cdb3dcea
@ -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 } from '../utils'
|
import { buildChatItemTree, getProcessedSystemVariablesFromUrlParams } 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 {
|
||||||
@ -106,6 +106,13 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
|||||||
}, [isInstalledApp, installedAppInfo, appInfo])
|
}, [isInstalledApp, installedAppInfo, appInfo])
|
||||||
const appId = useMemo(() => appData?.app_id, [appData])
|
const appId = useMemo(() => appData?.app_id, [appData])
|
||||||
|
|
||||||
|
const [userId, setUserId] = useState<string>()
|
||||||
|
useEffect(() => {
|
||||||
|
getProcessedSystemVariablesFromUrlParams().then(({ user_id }) => {
|
||||||
|
setUserId(user_id)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (appData?.site.default_language)
|
if (appData?.site.default_language)
|
||||||
changeLanguage(appData.site.default_language)
|
changeLanguage(appData.site.default_language)
|
||||||
@ -124,18 +131,24 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
|||||||
setSidebarCollapseState(localState === 'collapsed')
|
setSidebarCollapseState(localState === 'collapsed')
|
||||||
}
|
}
|
||||||
}, [appId])
|
}, [appId])
|
||||||
const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, string>>(CONVERSATION_ID_INFO, {
|
const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, Record<string, string>>>(CONVERSATION_ID_INFO, {
|
||||||
defaultValue: {},
|
defaultValue: {},
|
||||||
})
|
})
|
||||||
const currentConversationId = useMemo(() => conversationIdInfo?.[appId || ''] || '', [appId, conversationIdInfo])
|
const currentConversationId = useMemo(() => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || '', [appId, conversationIdInfo, userId])
|
||||||
const handleConversationIdInfoChange = useCallback((changeConversationId: string) => {
|
const handleConversationIdInfoChange = useCallback((changeConversationId: string) => {
|
||||||
if (appId) {
|
if (appId) {
|
||||||
|
let prevValue = conversationIdInfo?.[appId || '']
|
||||||
|
if (typeof prevValue === 'string')
|
||||||
|
prevValue = {}
|
||||||
setConversationIdInfo({
|
setConversationIdInfo({
|
||||||
...conversationIdInfo,
|
...conversationIdInfo,
|
||||||
[appId || '']: changeConversationId,
|
[appId || '']: {
|
||||||
|
...prevValue,
|
||||||
|
[userId || 'DEFAULT']: changeConversationId,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [appId, conversationIdInfo, setConversationIdInfo])
|
}, [appId, conversationIdInfo, setConversationIdInfo, userId])
|
||||||
|
|
||||||
const [newConversationId, setNewConversationId] = useState('')
|
const [newConversationId, setNewConversationId] = useState('')
|
||||||
const chatShouldReloadKey = useMemo(() => {
|
const chatShouldReloadKey = useMemo(() => {
|
||||||
|
@ -15,7 +15,7 @@ import type {
|
|||||||
Feedback,
|
Feedback,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
import { CONVERSATION_ID_INFO } from '../constants'
|
import { CONVERSATION_ID_INFO } from '../constants'
|
||||||
import { buildChatItemTree, getProcessedInputsFromUrlParams } from '../utils'
|
import { buildChatItemTree, getProcessedInputsFromUrlParams, getProcessedSystemVariablesFromUrlParams } from '../utils'
|
||||||
import { getProcessedFilesFromResponse } from '../../file-uploader/utils'
|
import { getProcessedFilesFromResponse } from '../../file-uploader/utils'
|
||||||
import {
|
import {
|
||||||
fetchAppInfo,
|
fetchAppInfo,
|
||||||
@ -72,23 +72,36 @@ export const useEmbeddedChatbot = () => {
|
|||||||
}, [appInfo])
|
}, [appInfo])
|
||||||
const appId = useMemo(() => appData?.app_id, [appData])
|
const appId = useMemo(() => appData?.app_id, [appData])
|
||||||
|
|
||||||
|
const [userId, setUserId] = useState<string>()
|
||||||
|
useEffect(() => {
|
||||||
|
getProcessedSystemVariablesFromUrlParams().then(({ user_id }) => {
|
||||||
|
setUserId(user_id)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (appInfo?.site.default_language)
|
if (appInfo?.site.default_language)
|
||||||
changeLanguage(appInfo.site.default_language)
|
changeLanguage(appInfo.site.default_language)
|
||||||
}, [appInfo])
|
}, [appInfo])
|
||||||
|
|
||||||
const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, string>>(CONVERSATION_ID_INFO, {
|
const [conversationIdInfo, setConversationIdInfo] = useLocalStorageState<Record<string, Record<string, string>>>(CONVERSATION_ID_INFO, {
|
||||||
defaultValue: {},
|
defaultValue: {},
|
||||||
})
|
})
|
||||||
const currentConversationId = useMemo(() => conversationIdInfo?.[appId || ''] || '', [appId, conversationIdInfo])
|
const currentConversationId = useMemo(() => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || '', [appId, conversationIdInfo, userId])
|
||||||
const handleConversationIdInfoChange = useCallback((changeConversationId: string) => {
|
const handleConversationIdInfoChange = useCallback((changeConversationId: string) => {
|
||||||
if (appId) {
|
if (appId) {
|
||||||
|
let prevValue = conversationIdInfo?.[appId || '']
|
||||||
|
if (typeof prevValue === 'string')
|
||||||
|
prevValue = {}
|
||||||
setConversationIdInfo({
|
setConversationIdInfo({
|
||||||
...conversationIdInfo,
|
...conversationIdInfo,
|
||||||
[appId || '']: changeConversationId,
|
[appId || '']: {
|
||||||
|
...prevValue,
|
||||||
|
[userId || 'DEFAULT']: changeConversationId,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [appId, conversationIdInfo, setConversationIdInfo])
|
}, [appId, conversationIdInfo, setConversationIdInfo, userId])
|
||||||
|
|
||||||
const [newConversationId, setNewConversationId] = useState('')
|
const [newConversationId, setNewConversationId] = useState('')
|
||||||
const chatShouldReloadKey = useMemo(() => {
|
const chatShouldReloadKey = useMemo(() => {
|
||||||
|
@ -2,29 +2,44 @@ import { CONVERSATION_ID_INFO } from '../base/chat/constants'
|
|||||||
import { fetchAccessToken } from '@/service/share'
|
import { fetchAccessToken } from '@/service/share'
|
||||||
import { getProcessedSystemVariablesFromUrlParams } from '../base/chat/utils'
|
import { getProcessedSystemVariablesFromUrlParams } from '../base/chat/utils'
|
||||||
|
|
||||||
|
export const isTokenV1 = (token: Record<string, any>) => {
|
||||||
|
return !token.version
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getInitialTokenV2 = (): Record<string, any> => ({
|
||||||
|
version: 2,
|
||||||
|
})
|
||||||
|
|
||||||
export const checkOrSetAccessToken = async () => {
|
export const checkOrSetAccessToken = async () => {
|
||||||
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
||||||
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
|
const userId = (await getProcessedSystemVariablesFromUrlParams()).user_id
|
||||||
let accessTokenJson = { [sharedToken]: '' }
|
const accessToken = localStorage.getItem('token') || JSON.stringify(getInitialTokenV2())
|
||||||
|
let accessTokenJson = getInitialTokenV2()
|
||||||
try {
|
try {
|
||||||
accessTokenJson = JSON.parse(accessToken)
|
accessTokenJson = JSON.parse(accessToken)
|
||||||
|
if (isTokenV1(accessTokenJson))
|
||||||
|
accessTokenJson = getInitialTokenV2()
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!accessTokenJson[sharedToken]) {
|
if (!accessTokenJson[sharedToken]?.[userId || 'DEFAULT']) {
|
||||||
const sysUserId = (await getProcessedSystemVariablesFromUrlParams()).user_id
|
const res = await fetchAccessToken(sharedToken, userId)
|
||||||
const res = await fetchAccessToken(sharedToken, sysUserId)
|
accessTokenJson[sharedToken] = {
|
||||||
accessTokenJson[sharedToken] = res.access_token
|
...accessTokenJson[sharedToken],
|
||||||
|
[userId || 'DEFAULT']: res.access_token,
|
||||||
|
}
|
||||||
localStorage.setItem('token', JSON.stringify(accessTokenJson))
|
localStorage.setItem('token', JSON.stringify(accessTokenJson))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setAccessToken = async (sharedToken: string, token: string) => {
|
export const setAccessToken = async (sharedToken: string, token: string, user_id?: string) => {
|
||||||
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
|
const accessToken = localStorage.getItem('token') || JSON.stringify(getInitialTokenV2())
|
||||||
let accessTokenJson = { [sharedToken]: '' }
|
let accessTokenJson = getInitialTokenV2()
|
||||||
try {
|
try {
|
||||||
accessTokenJson = JSON.parse(accessToken)
|
accessTokenJson = JSON.parse(accessToken)
|
||||||
|
if (isTokenV1(accessTokenJson))
|
||||||
|
accessTokenJson = getInitialTokenV2()
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
@ -32,17 +47,22 @@ export const setAccessToken = async (sharedToken: string, token: string) => {
|
|||||||
|
|
||||||
localStorage.removeItem(CONVERSATION_ID_INFO)
|
localStorage.removeItem(CONVERSATION_ID_INFO)
|
||||||
|
|
||||||
accessTokenJson[sharedToken] = token
|
accessTokenJson[sharedToken] = {
|
||||||
|
...accessTokenJson[sharedToken],
|
||||||
|
[user_id || 'DEFAULT']: token,
|
||||||
|
}
|
||||||
localStorage.setItem('token', JSON.stringify(accessTokenJson))
|
localStorage.setItem('token', JSON.stringify(accessTokenJson))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeAccessToken = () => {
|
export const removeAccessToken = () => {
|
||||||
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
||||||
|
|
||||||
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
|
const accessToken = localStorage.getItem('token') || JSON.stringify(getInitialTokenV2())
|
||||||
let accessTokenJson = { [sharedToken]: '' }
|
let accessTokenJson = getInitialTokenV2()
|
||||||
try {
|
try {
|
||||||
accessTokenJson = JSON.parse(accessToken)
|
accessTokenJson = JSON.parse(accessToken)
|
||||||
|
if (isTokenV1(accessTokenJson))
|
||||||
|
accessTokenJson = getInitialTokenV2()
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
|
@ -287,9 +287,9 @@ const handleStream = (
|
|||||||
|
|
||||||
const baseFetch = base
|
const baseFetch = base
|
||||||
|
|
||||||
export const upload = (options: any, isPublicAPI?: boolean, url?: string, searchParams?: string): Promise<any> => {
|
export const upload = async (options: any, isPublicAPI?: boolean, url?: string, searchParams?: string): Promise<any> => {
|
||||||
const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
|
const urlPrefix = isPublicAPI ? PUBLIC_API_PREFIX : API_PREFIX
|
||||||
const token = getAccessToken(isPublicAPI)
|
const token = await getAccessToken(isPublicAPI)
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: (url ? `${urlPrefix}${url}` : `${urlPrefix}/files/upload`) + (searchParams || ''),
|
url: (url ? `${urlPrefix}${url}` : `${urlPrefix}/files/upload`) + (searchParams || ''),
|
||||||
@ -324,7 +324,7 @@ export const upload = (options: any, isPublicAPI?: boolean, url?: string, search
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ssePost = (
|
export const ssePost = async (
|
||||||
url: string,
|
url: string,
|
||||||
fetchOptions: FetchOptionType,
|
fetchOptions: FetchOptionType,
|
||||||
otherOptions: IOtherOptions,
|
otherOptions: IOtherOptions,
|
||||||
@ -385,7 +385,7 @@ export const ssePost = (
|
|||||||
if (body)
|
if (body)
|
||||||
options.body = JSON.stringify(body)
|
options.body = JSON.stringify(body)
|
||||||
|
|
||||||
const accessToken = getAccessToken(isPublicAPI)
|
const accessToken = await getAccessToken(isPublicAPI)
|
||||||
; (options.headers as Headers).set('Authorization', `Bearer ${accessToken}`)
|
; (options.headers as Headers).set('Authorization', `Bearer ${accessToken}`)
|
||||||
|
|
||||||
globalThis.fetch(urlWithPrefix, options as RequestInit)
|
globalThis.fetch(urlWithPrefix, options as RequestInit)
|
||||||
|
@ -3,6 +3,8 @@ import ky from 'ky'
|
|||||||
import type { IOtherOptions } from './base'
|
import type { IOtherOptions } from './base'
|
||||||
import Toast from '@/app/components/base/toast'
|
import Toast from '@/app/components/base/toast'
|
||||||
import { API_PREFIX, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX } from '@/config'
|
import { API_PREFIX, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX } from '@/config'
|
||||||
|
import { getInitialTokenV2, isTokenV1 } from '@/app/components/share/utils'
|
||||||
|
import { getProcessedSystemVariablesFromUrlParams } from '@/app/components/base/chat/utils'
|
||||||
|
|
||||||
const TIME_OUT = 100000
|
const TIME_OUT = 100000
|
||||||
|
|
||||||
@ -67,44 +69,34 @@ const beforeErrorToast = (otherOptions: IOtherOptions): BeforeErrorHook => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getPublicToken = () => {
|
export async function getAccessToken(isPublicAPI?: boolean) {
|
||||||
let token = ''
|
|
||||||
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
|
||||||
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
|
|
||||||
let accessTokenJson = { [sharedToken]: '' }
|
|
||||||
try {
|
|
||||||
accessTokenJson = JSON.parse(accessToken)
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
token = accessTokenJson[sharedToken]
|
|
||||||
return token || ''
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAccessToken(isPublicAPI?: boolean) {
|
|
||||||
if (isPublicAPI) {
|
if (isPublicAPI) {
|
||||||
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
||||||
const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
|
const userId = (await getProcessedSystemVariablesFromUrlParams()).user_id
|
||||||
let accessTokenJson = { [sharedToken]: '' }
|
const accessToken = localStorage.getItem('token') || JSON.stringify({ version: 2 })
|
||||||
|
let accessTokenJson: Record<string, any> = { version: 2 }
|
||||||
try {
|
try {
|
||||||
accessTokenJson = JSON.parse(accessToken)
|
accessTokenJson = JSON.parse(accessToken)
|
||||||
|
if (isTokenV1(accessTokenJson))
|
||||||
|
accessTokenJson = getInitialTokenV2()
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
}
|
}
|
||||||
return accessTokenJson[sharedToken]
|
return accessTokenJson[sharedToken]?.[userId || 'DEFAULT']
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return localStorage.getItem('console_token') || ''
|
return localStorage.getItem('console_token') || ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const beforeRequestPublicAuthorization: BeforeRequestHook = (request) => {
|
const beforeRequestPublicAuthorization: BeforeRequestHook = async (request) => {
|
||||||
const token = getAccessToken(true)
|
const token = await getAccessToken(true)
|
||||||
request.headers.set('Authorization', `Bearer ${token}`)
|
request.headers.set('Authorization', `Bearer ${token}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const beforeRequestAuthorization: BeforeRequestHook = (request) => {
|
const beforeRequestAuthorization: BeforeRequestHook = async (request) => {
|
||||||
const accessToken = getAccessToken()
|
const accessToken = await getAccessToken()
|
||||||
request.headers.set('Authorization', `Bearer ${accessToken}`)
|
request.headers.set('Authorization', `Bearer ${accessToken}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user