Merge remote-tracking branch 'origin/main' into feat/support-agent-sandbox

# Conflicts:
#	web/eslint-suppressions.json
#	web/service/debug.ts
This commit is contained in:
yyh
2026-01-22 22:40:32 +08:00
184 changed files with 3974 additions and 744 deletions

View File

@ -1,4 +1,5 @@
import type { AccessMode } from '@/models/access-control'
import type { Banner } from '@/models/app'
import type { App, AppCategory } from '@/models/explore'
import { del, get, patch } from './base'
@ -9,6 +10,7 @@ export const fetchAppList = () => {
}>('/explore/apps')
}
// eslint-disable-next-line ts/no-explicit-any
export const fetchAppDetail = (id: string): Promise<any> => {
return get(`/explore/apps/${id}`)
}
@ -32,3 +34,8 @@ export const updatePinStatus = (id: string, isPinned: boolean) => {
export const getAppAccessModeByAppId = (appId: string) => {
return get<{ accessMode: AccessMode }>(`/enterprise/webapp/app/access-mode?appId=${appId}`)
}
export const fetchBanners = (language?: string): Promise<Banner[]> => {
const url = language ? `/explore/banners?language=${language}` : '/explore/banners'
return get<Banner[]>(url)
}

View File

@ -2,22 +2,17 @@ import type {
IOnCompleted,
IOnData,
IOnError,
IOnFile,
IOnIterationFinished,
IOnIterationNext,
IOnIterationStarted,
IOnLoopFinished,
IOnLoopNext,
IOnLoopStarted,
IOnMessageEnd,
IOnMessageReplace,
IOnNodeFinished,
IOnNodeStarted,
IOnTextChunk,
IOnTextReplace,
IOnThought,
IOnTTSChunk,
IOnTTSEnd,
IOnWorkflowFinished,
IOnWorkflowStarted,
} from './base'
@ -44,45 +39,43 @@ import {
} from './base'
import { getWebAppAccessToken } from './webapp-auth'
function getAction(action: 'get' | 'post' | 'del' | 'patch', isInstalledApp: boolean) {
export enum AppSourceType {
webApp = 'webApp',
installedApp = 'installedApp',
tryApp = 'tryApp',
}
const apiPrefix = {
[AppSourceType.webApp]: '',
[AppSourceType.installedApp]: 'installed-apps',
[AppSourceType.tryApp]: 'trial-apps',
}
function getIsPublicAPI(appSourceType: AppSourceType) {
return appSourceType === AppSourceType.webApp
}
function getAction(action: 'get' | 'post' | 'del' | 'patch', appSourceType: AppSourceType) {
const isNeedLogin = !getIsPublicAPI(appSourceType)
switch (action) {
case 'get':
return isInstalledApp ? consoleGet : get
return isNeedLogin ? consoleGet : get
case 'post':
return isInstalledApp ? consolePost : post
return isNeedLogin ? consolePost : post
case 'patch':
return isInstalledApp ? consolePatch : patch
return isNeedLogin ? consolePatch : patch
case 'del':
return isInstalledApp ? consoleDel : del
return isNeedLogin ? consoleDel : del
}
}
export function getUrl(url: string, isInstalledApp: boolean, installedAppId: string) {
return isInstalledApp ? `installed-apps/${installedAppId}/${url.startsWith('/') ? url.slice(1) : url}` : url
export function getUrl(url: string, appSourceType: AppSourceType, appId: string) {
const hasPrefix = appSourceType !== AppSourceType.webApp
return hasPrefix ? `${apiPrefix[appSourceType]}/${appId}/${url.startsWith('/') ? url.slice(1) : url}` : url
}
export const sendChatMessage = async (body: Record<string, any>, { onData, onCompleted, onThought, onFile, onError, getAbortController, onMessageEnd, onMessageReplace, onTTSChunk, onTTSEnd }: {
onData: IOnData
onCompleted: IOnCompleted
onFile: IOnFile
onThought: IOnThought
onError: IOnError
onMessageEnd?: IOnMessageEnd
onMessageReplace?: IOnMessageReplace
getAbortController?: (abortController: AbortController) => void
onTTSChunk?: IOnTTSChunk
onTTSEnd?: IOnTTSEnd
}, isInstalledApp: boolean, installedAppId = '') => {
return ssePost(getUrl('chat-messages', isInstalledApp, installedAppId), {
body: {
...body,
response_mode: 'streaming',
},
}, { onData, onCompleted, onThought, onFile, isPublicAPI: !isInstalledApp, onError, getAbortController, onMessageEnd, onMessageReplace, onTTSChunk, onTTSEnd })
}
export const stopChatMessageResponding = async (appId: string, taskId: string, isInstalledApp: boolean, installedAppId = '') => {
return getAction('post', isInstalledApp)(getUrl(`chat-messages/${taskId}/stop`, isInstalledApp, installedAppId))
export const stopChatMessageResponding = async (appId: string, taskId: string, appSourceType: AppSourceType, installedAppId = '') => {
return getAction('post', appSourceType)(getUrl(`chat-messages/${taskId}/stop`, appSourceType, installedAppId))
}
export const sendCompletionMessage = async (body: Record<string, any>, { onData, onCompleted, onError, onMessageReplace, getAbortController }: {
@ -91,13 +84,13 @@ export const sendCompletionMessage = async (body: Record<string, any>, { onData,
onError: IOnError
onMessageReplace: IOnMessageReplace
getAbortController?: (abortController: AbortController) => void
}, isInstalledApp: boolean, installedAppId = '') => {
return ssePost(getUrl('completion-messages', isInstalledApp, installedAppId), {
}, appSourceType: AppSourceType, installedAppId = '') => {
return ssePost(getUrl('completion-messages', appSourceType, installedAppId), {
body: {
...body,
response_mode: 'streaming',
},
}, { onData, onCompleted, isPublicAPI: !isInstalledApp, onError, onMessageReplace, getAbortController })
}, { onData, onCompleted, isPublicAPI: getIsPublicAPI(appSourceType), onError, onMessageReplace, getAbortController })
}
export const sendWorkflowMessage = async (
@ -129,10 +122,10 @@ export const sendWorkflowMessage = async (
onTextChunk: IOnTextChunk
onTextReplace: IOnTextReplace
},
isInstalledApp: boolean,
installedAppId = '',
appSourceType: AppSourceType,
appId = '',
) => {
return ssePost(getUrl('workflows/run', isInstalledApp, installedAppId), {
return ssePost(getUrl('workflows/run', appSourceType, appId), {
body: {
...body,
response_mode: 'streaming',
@ -141,7 +134,7 @@ export const sendWorkflowMessage = async (
onNodeStarted,
onWorkflowStarted,
onWorkflowFinished,
isPublicAPI: !isInstalledApp,
isPublicAPI: getIsPublicAPI(appSourceType),
onNodeFinished,
onIterationStart,
onIterationNext,
@ -154,42 +147,42 @@ export const sendWorkflowMessage = async (
})
}
export const stopWorkflowMessage = async (_appId: string, taskId: string, isInstalledApp: boolean, installedAppId = '') => {
export const stopWorkflowMessage = async (_appId: string, taskId: string, appSourceType: AppSourceType, installedAppId = '') => {
if (!taskId)
return
return getAction('post', isInstalledApp)(getUrl(`workflows/tasks/${taskId}/stop`, isInstalledApp, installedAppId))
return getAction('post', appSourceType)(getUrl(`workflows/tasks/${taskId}/stop`, appSourceType, installedAppId))
}
export const fetchAppInfo = async () => {
return get('/site') as Promise<AppData>
}
export const fetchConversations = async (isInstalledApp: boolean, installedAppId = '', last_id?: string, pinned?: boolean, limit?: number) => {
return getAction('get', isInstalledApp)(getUrl('conversations', isInstalledApp, installedAppId), { params: { limit: limit || 20, ...(last_id ? { last_id } : {}), ...(pinned !== undefined ? { pinned } : {}) } }) as Promise<AppConversationData>
export const fetchConversations = async (appSourceType: AppSourceType, installedAppId = '', last_id?: string, pinned?: boolean, limit?: number) => {
return getAction('get', appSourceType)(getUrl('conversations', appSourceType, installedAppId), { params: { limit: limit || 20, ...(last_id ? { last_id } : {}), ...(pinned !== undefined ? { pinned } : {}) } }) as Promise<AppConversationData>
}
export const pinConversation = async (isInstalledApp: boolean, installedAppId = '', id: string) => {
return getAction('patch', isInstalledApp)(getUrl(`conversations/${id}/pin`, isInstalledApp, installedAppId))
export const pinConversation = async (appSourceType: AppSourceType, installedAppId = '', id: string) => {
return getAction('patch', appSourceType)(getUrl(`conversations/${id}/pin`, appSourceType, installedAppId))
}
export const unpinConversation = async (isInstalledApp: boolean, installedAppId = '', id: string) => {
return getAction('patch', isInstalledApp)(getUrl(`conversations/${id}/unpin`, isInstalledApp, installedAppId))
export const unpinConversation = async (appSourceType: AppSourceType, installedAppId = '', id: string) => {
return getAction('patch', appSourceType)(getUrl(`conversations/${id}/unpin`, appSourceType, installedAppId))
}
export const delConversation = async (isInstalledApp: boolean, installedAppId = '', id: string) => {
return getAction('del', isInstalledApp)(getUrl(`conversations/${id}`, isInstalledApp, installedAppId))
export const delConversation = async (appSourceType: AppSourceType, installedAppId = '', id: string) => {
return getAction('del', appSourceType)(getUrl(`conversations/${id}`, appSourceType, installedAppId))
}
export const renameConversation = async (isInstalledApp: boolean, installedAppId = '', id: string, name: string) => {
return getAction('post', isInstalledApp)(getUrl(`conversations/${id}/name`, isInstalledApp, installedAppId), { body: { name } })
export const renameConversation = async (appSourceType: AppSourceType, installedAppId = '', id: string, name: string) => {
return getAction('post', appSourceType)(getUrl(`conversations/${id}/name`, appSourceType, installedAppId), { body: { name } })
}
export const generationConversationName = async (isInstalledApp: boolean, installedAppId = '', id: string) => {
return getAction('post', isInstalledApp)(getUrl(`conversations/${id}/name`, isInstalledApp, installedAppId), { body: { auto_generate: true } }) as Promise<ConversationItem>
export const generationConversationName = async (appSourceType: AppSourceType, installedAppId = '', id: string) => {
return getAction('post', appSourceType)(getUrl(`conversations/${id}/name`, appSourceType, installedAppId), { body: { auto_generate: true } }) as Promise<ConversationItem>
}
export const fetchChatList = async (conversationId: string, isInstalledApp: boolean, installedAppId = '') => {
return getAction('get', isInstalledApp)(getUrl('messages', isInstalledApp, installedAppId), { params: { conversation_id: conversationId, limit: 20, last_id: '' } }) as any
export const fetchChatList = async (conversationId: string, appSourceType: AppSourceType, installedAppId = '') => {
return getAction('get', appSourceType)(getUrl('messages', appSourceType, installedAppId), { params: { conversation_id: conversationId, limit: 20, last_id: '' } }) as any
}
// Abandoned API interface
@ -198,12 +191,12 @@ export const fetchChatList = async (conversationId: string, isInstalledApp: bool
// }
// init value. wait for server update
export const fetchAppParams = async (isInstalledApp: boolean, installedAppId = '') => {
return (getAction('get', isInstalledApp))(getUrl('parameters', isInstalledApp, installedAppId)) as Promise<ChatConfig>
export const fetchAppParams = async (appSourceType: AppSourceType, appId = '') => {
return (getAction('get', appSourceType))(getUrl('parameters', appSourceType, appId)) as Promise<ChatConfig>
}
export const fetchWebSAMLSSOUrl = async (appCode: string, redirectUrl: string) => {
return (getAction('get', false))(getUrl('/enterprise/sso/saml/login', false, ''), {
return (getAction('get', AppSourceType.webApp))(getUrl('/enterprise/sso/saml/login', AppSourceType.webApp, ''), {
params: {
app_code: appCode,
redirect_url: redirectUrl,
@ -212,7 +205,7 @@ export const fetchWebSAMLSSOUrl = async (appCode: string, redirectUrl: string) =
}
export const fetchWebOIDCSSOUrl = async (appCode: string, redirectUrl: string) => {
return (getAction('get', false))(getUrl('/enterprise/sso/oidc/login', false, ''), {
return (getAction('get', AppSourceType.webApp))(getUrl('/enterprise/sso/oidc/login', AppSourceType.webApp, ''), {
params: {
app_code: appCode,
redirect_url: redirectUrl,
@ -222,7 +215,7 @@ export const fetchWebOIDCSSOUrl = async (appCode: string, redirectUrl: string) =
}
export const fetchWebOAuth2SSOUrl = async (appCode: string, redirectUrl: string) => {
return (getAction('get', false))(getUrl('/enterprise/sso/oauth2/login', false, ''), {
return (getAction('get', AppSourceType.webApp))(getUrl('/enterprise/sso/oauth2/login', AppSourceType.webApp, ''), {
params: {
app_code: appCode,
redirect_url: redirectUrl,
@ -231,7 +224,7 @@ export const fetchWebOAuth2SSOUrl = async (appCode: string, redirectUrl: string)
}
export const fetchMembersSAMLSSOUrl = async (appCode: string, redirectUrl: string) => {
return (getAction('get', false))(getUrl('/enterprise/sso/members/saml/login', false, ''), {
return (getAction('get', AppSourceType.webApp))(getUrl('/enterprise/sso/members/saml/login', AppSourceType.webApp, ''), {
params: {
app_code: appCode,
redirect_url: redirectUrl,
@ -240,7 +233,7 @@ export const fetchMembersSAMLSSOUrl = async (appCode: string, redirectUrl: strin
}
export const fetchMembersOIDCSSOUrl = async (appCode: string, redirectUrl: string) => {
return (getAction('get', false))(getUrl('/enterprise/sso/members/oidc/login', false, ''), {
return (getAction('get', AppSourceType.webApp))(getUrl('/enterprise/sso/members/oidc/login', AppSourceType.webApp, ''), {
params: {
app_code: appCode,
redirect_url: redirectUrl,
@ -250,7 +243,7 @@ export const fetchMembersOIDCSSOUrl = async (appCode: string, redirectUrl: strin
}
export const fetchMembersOAuth2SSOUrl = async (appCode: string, redirectUrl: string) => {
return (getAction('get', false))(getUrl('/enterprise/sso/members/oauth2/login', false, ''), {
return (getAction('get', AppSourceType.webApp))(getUrl('/enterprise/sso/members/oauth2/login', AppSourceType.webApp, ''), {
params: {
app_code: appCode,
redirect_url: redirectUrl,
@ -258,48 +251,50 @@ export const fetchMembersOAuth2SSOUrl = async (appCode: string, redirectUrl: str
}) as Promise<{ url: string }>
}
export const fetchAppMeta = async (isInstalledApp: boolean, installedAppId = '') => {
return (getAction('get', isInstalledApp))(getUrl('meta', isInstalledApp, installedAppId)) as Promise<AppMeta>
export const fetchAppMeta = async (appSourceType: AppSourceType, installedAppId = '') => {
return (getAction('get', appSourceType))(getUrl('meta', appSourceType, installedAppId)) as Promise<AppMeta>
}
export const updateFeedback = async ({ url, body }: { url: string, body: FeedbackType }, isInstalledApp: boolean, installedAppId = '') => {
return (getAction('post', isInstalledApp))(getUrl(url, isInstalledApp, installedAppId), { body })
export const updateFeedback = async ({ url, body }: { url: string, body: FeedbackType }, appSourceType: AppSourceType, installedAppId = '') => {
return (getAction('post', appSourceType))(getUrl(url, appSourceType, installedAppId), { body })
}
export const fetchMoreLikeThis = async (messageId: string, isInstalledApp: boolean, installedAppId = '') => {
return (getAction('get', isInstalledApp))(getUrl(`/messages/${messageId}/more-like-this`, isInstalledApp, installedAppId), {
export const fetchMoreLikeThis = async (messageId: string, appSourceType: AppSourceType, installedAppId = '') => {
return (getAction('get', appSourceType))(getUrl(`/messages/${messageId}/more-like-this`, appSourceType, installedAppId), {
params: {
response_mode: 'blocking',
},
})
}
export const saveMessage = (messageId: string, isInstalledApp: boolean, installedAppId = '') => {
return (getAction('post', isInstalledApp))(getUrl('/saved-messages', isInstalledApp, installedAppId), { body: { message_id: messageId } })
export const saveMessage = (messageId: string, appSourceType: AppSourceType, installedAppId = '') => {
return (getAction('post', appSourceType))(getUrl('/saved-messages', appSourceType, installedAppId), { body: { message_id: messageId } })
}
export const fetchSavedMessage = async (isInstalledApp: boolean, installedAppId = '') => {
return (getAction('get', isInstalledApp))(getUrl('/saved-messages', isInstalledApp, installedAppId))
export const fetchSavedMessage = async (appSourceType: AppSourceType, installedAppId = '') => {
return (getAction('get', appSourceType))(getUrl('/saved-messages', appSourceType, installedAppId), {}, {
silent: true,
})
}
export const removeMessage = (messageId: string, isInstalledApp: boolean, installedAppId = '') => {
return (getAction('del', isInstalledApp))(getUrl(`/saved-messages/${messageId}`, isInstalledApp, installedAppId))
export const removeMessage = (messageId: string, appSourceType: AppSourceType, installedAppId = '') => {
return (getAction('del', appSourceType))(getUrl(`/saved-messages/${messageId}`, appSourceType, installedAppId))
}
export const fetchSuggestedQuestions = (messageId: string, isInstalledApp: boolean, installedAppId = '') => {
return (getAction('get', isInstalledApp))(getUrl(`/messages/${messageId}/suggested-questions`, isInstalledApp, installedAppId))
export const fetchSuggestedQuestions = (messageId: string, appSourceType: AppSourceType, installedAppId = '') => {
return (getAction('get', appSourceType))(getUrl(`/messages/${messageId}/suggested-questions`, appSourceType, installedAppId))
}
export const audioToText = (url: string, isPublicAPI: boolean, body: FormData) => {
return (getAction('post', !isPublicAPI))(url, { body }, { bodyStringify: false, deleteContentType: true }) as Promise<{ text: string }>
export const audioToText = (url: string, appSourceType: AppSourceType, body: FormData) => {
return (getAction('post', appSourceType))(url, { body }, { bodyStringify: false, deleteContentType: true }) as Promise<{ text: string }>
}
export const textToAudio = (url: string, isPublicAPI: boolean, body: FormData) => {
return (getAction('post', !isPublicAPI))(url, { body }, { bodyStringify: false, deleteContentType: true }) as Promise<{ data: string }>
export const textToAudioStream = (url: string, appSourceType: AppSourceType, header: { content_type: string }, body: { streaming: boolean, voice?: string, message_id?: string, text?: string | null | undefined }) => {
return (getAction('post', appSourceType))(url, { body, header }, { needAllResponseContent: true })
}
export const textToAudioStream = (url: string, isPublicAPI: boolean, header: { content_type: string }, body: { streaming: boolean, voice?: string, message_id?: string, text?: string | null | undefined }) => {
return (getAction('post', !isPublicAPI))(url, { body, header }, { needAllResponseContent: true })
export const textToAudio = (url: string, appSourceType: AppSourceType, body: FormData) => {
return (getAction('post', appSourceType))(url, { body }, { bodyStringify: false, deleteContentType: true }) as Promise<{ data: string }>
}
export const fetchAccessToken = async ({ userId, appCode }: { userId?: string, appCode: string }) => {

26
web/service/try-app.ts Normal file
View File

@ -0,0 +1,26 @@
import type { ChatConfig } from '@/app/components/base/chat/types'
import type { DataSetListResponse } from '@/models/datasets'
import type { TryAppFlowPreview, TryAppInfo } from '@/models/try-app'
import { consoleClient } from '@/service/client'
export const fetchTryAppInfo = (appId: string): Promise<TryAppInfo> => {
return consoleClient.trialApps.info({ params: { appId } })
}
export const fetchTryAppDatasets = (appId: string, ids: string[]): Promise<DataSetListResponse> => {
return consoleClient.trialApps.datasets({
params: { appId },
query: { ids },
})
}
export const fetchTryAppFlowPreview = (appId: string): Promise<TryAppFlowPreview> => {
return consoleClient.trialApps.workflows({ params: { appId } })
.then(res => res as TryAppFlowPreview)
}
export const fetchTryAppParams = (appId: string): Promise<ChatConfig> => {
return consoleClient.trialApps.parameters({ params: { appId } })
}
export type { TryAppInfo } from '@/models/try-app'

View File

@ -2,8 +2,8 @@ import type { App, AppCategory } from '@/models/explore'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { AccessMode } from '@/models/access-control'
import { fetchAppList, fetchInstalledAppList, getAppAccessModeByAppId, uninstallApp, updatePinStatus } from './explore'
import { fetchAppMeta, fetchAppParams } from './share'
import { fetchAppList, fetchBanners, fetchInstalledAppList, getAppAccessModeByAppId, uninstallApp, updatePinStatus } from './explore'
import { AppSourceType, fetchAppMeta, fetchAppParams } from './share'
const NAME_SPACE = 'explore'
@ -81,7 +81,7 @@ export const useGetInstalledAppParams = (appId: string | null) => {
queryFn: () => {
if (!appId || appId.length === 0)
return Promise.reject(new Error('App ID is required to get app params'))
return fetchAppParams(true, appId)
return fetchAppParams(AppSourceType.installedApp, appId)
},
enabled: !!appId,
})
@ -93,8 +93,17 @@ export const useGetInstalledAppMeta = (appId: string | null) => {
queryFn: () => {
if (!appId || appId.length === 0)
return Promise.reject(new Error('App ID is required to get app meta'))
return fetchAppMeta(true, appId)
return fetchAppMeta(AppSourceType.installedApp, appId)
},
enabled: !!appId,
})
}
export const useGetBanners = (locale?: string) => {
return useQuery({
queryKey: [NAME_SPACE, 'banners', locale],
queryFn: () => {
return fetchBanners(locale)
},
})
}

View File

@ -3,6 +3,7 @@ import type { AppConversationData, ConversationItem } from '@/models/share'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { act, renderHook, waitFor } from '@testing-library/react'
import {
AppSourceType,
fetchChatList,
fetchConversations,
generationConversationName,
@ -15,15 +16,19 @@ import {
useShareConversations,
} from './use-share'
vi.mock('./share', () => ({
fetchChatList: vi.fn(),
fetchConversations: vi.fn(),
generationConversationName: vi.fn(),
fetchAppInfo: vi.fn(),
fetchAppMeta: vi.fn(),
fetchAppParams: vi.fn(),
getAppAccessModeByAppCode: vi.fn(),
}))
vi.mock('./share', async (importOriginal) => {
const actual = await importOriginal<typeof import('./share')>()
return {
...actual,
fetchChatList: vi.fn(),
fetchConversations: vi.fn(),
generationConversationName: vi.fn(),
fetchAppInfo: vi.fn(),
fetchAppMeta: vi.fn(),
fetchAppParams: vi.fn(),
getAppAccessModeByAppCode: vi.fn(),
}
})
const mockFetchConversations = vi.mocked(fetchConversations)
const mockFetchChatList = vi.mocked(fetchChatList)
@ -80,6 +85,7 @@ describe('useShareConversations', () => {
appId: undefined,
pinned: true,
limit: 50,
appSourceType: AppSourceType.webApp,
}
const response = createConversationData()
mockFetchConversations.mockResolvedValueOnce(response)
@ -89,7 +95,7 @@ describe('useShareConversations', () => {
// Assert
await waitFor(() => {
expect(mockFetchConversations).toHaveBeenCalledWith(false, undefined, undefined, true, 50)
expect(mockFetchConversations).toHaveBeenCalledWith(AppSourceType.webApp, undefined, undefined, true, 50)
})
await waitFor(() => {
expect(result.current.data).toEqual(response)
@ -102,6 +108,7 @@ describe('useShareConversations', () => {
const params = {
isInstalledApp: true,
appId: undefined,
appSourceType: AppSourceType.installedApp,
}
// Act
@ -127,6 +134,7 @@ describe('useShareChatList', () => {
conversationId: 'conversation-1',
isInstalledApp: true,
appId: 'app-1',
appSourceType: AppSourceType.installedApp,
}
const response = { data: [] }
mockFetchChatList.mockResolvedValueOnce(response)
@ -136,7 +144,7 @@ describe('useShareChatList', () => {
// Assert
await waitFor(() => {
expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', true, 'app-1')
expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', AppSourceType.installedApp, 'app-1')
})
await waitFor(() => {
expect(result.current.data).toEqual(response)
@ -149,6 +157,7 @@ describe('useShareChatList', () => {
conversationId: '',
isInstalledApp: false,
appId: undefined,
appSourceType: AppSourceType.webApp,
}
// Act
@ -171,6 +180,7 @@ describe('useShareChatList', () => {
conversationId: 'conversation-1',
isInstalledApp: false,
appId: undefined,
appSourceType: AppSourceType.webApp,
}
const initialResponse = { data: [{ id: '1', content: 'initial' }] }
const updatedResponse = { data: [{ id: '1', content: 'initial' }, { id: '2', content: 'new message' }] }
@ -219,6 +229,7 @@ describe('useShareConversationName', () => {
conversationId: 'conversation-2',
isInstalledApp: false,
appId: undefined,
appSourceType: AppSourceType.webApp,
}
const response = createConversationItem({ id: 'conversation-2', name: 'Generated' })
mockGenerationConversationName.mockResolvedValueOnce(response)
@ -228,7 +239,7 @@ describe('useShareConversationName', () => {
// Assert
await waitFor(() => {
expect(mockGenerationConversationName).toHaveBeenCalledWith(false, undefined, 'conversation-2')
expect(mockGenerationConversationName).toHaveBeenCalledWith(AppSourceType.webApp, undefined, 'conversation-2')
})
await waitFor(() => {
expect(result.current.data).toEqual(response)
@ -241,6 +252,7 @@ describe('useShareConversationName', () => {
conversationId: 'conversation-3',
isInstalledApp: false,
appId: undefined,
appSourceType: AppSourceType.webApp,
}
// Act

View File

@ -1,6 +1,7 @@
import type { AppConversationData, ConversationItem } from '@/models/share'
import { useQuery } from '@tanstack/react-query'
import {
AppSourceType,
fetchAppInfo,
fetchAppMeta,
fetchAppParams,
@ -14,7 +15,7 @@ import { useInvalid } from './use-base'
const NAME_SPACE = 'webapp'
type ShareConversationsParams = {
isInstalledApp: boolean
appSourceType: AppSourceType
appId?: string
lastId?: string
pinned?: boolean
@ -23,13 +24,13 @@ type ShareConversationsParams = {
type ShareChatListParams = {
conversationId: string
isInstalledApp: boolean
appSourceType: AppSourceType
appId?: string
}
type ShareConversationNameParams = {
conversationId: string
isInstalledApp: boolean
appSourceType: AppSourceType
appId?: string
}
@ -73,7 +74,7 @@ export const useGetWebAppParams = () => {
return useQuery({
queryKey: shareQueryKeys.appParams,
queryFn: () => {
return fetchAppParams(false)
return fetchAppParams(AppSourceType.webApp)
},
})
}
@ -82,7 +83,7 @@ export const useGetWebAppMeta = () => {
return useQuery({
queryKey: shareQueryKeys.appMeta,
queryFn: () => {
return fetchAppMeta(false)
return fetchAppMeta(AppSourceType.webApp)
},
})
}
@ -93,11 +94,11 @@ export const useShareConversations = (params: ShareConversationsParams, options:
refetchOnReconnect,
refetchOnWindowFocus,
} = options
const isEnabled = enabled && (!params.isInstalledApp || !!params.appId)
const isEnabled = enabled && params.appSourceType !== AppSourceType.tryApp && (params.appSourceType !== AppSourceType.installedApp || !!params.appId)
return useQuery<AppConversationData>({
queryKey: shareQueryKeys.conversationList(params),
queryFn: () => fetchConversations(
params.isInstalledApp,
params.appSourceType,
params.appId,
params.lastId,
params.pinned,
@ -115,10 +116,10 @@ export const useShareChatList = (params: ShareChatListParams, options: ShareQuer
refetchOnReconnect,
refetchOnWindowFocus,
} = options
const isEnabled = enabled && (!params.isInstalledApp || !!params.appId) && !!params.conversationId
const isEnabled = enabled && params.appSourceType !== AppSourceType.tryApp && (params.appSourceType !== AppSourceType.installedApp || !!params.appId) && !!params.conversationId
return useQuery({
queryKey: shareQueryKeys.chatList(params),
queryFn: () => fetchChatList(params.conversationId, params.isInstalledApp, params.appId),
queryFn: () => fetchChatList(params.conversationId, params.appSourceType, params.appId),
enabled: isEnabled,
refetchOnReconnect,
refetchOnWindowFocus,
@ -135,10 +136,10 @@ export const useShareConversationName = (params: ShareConversationNameParams, op
refetchOnReconnect,
refetchOnWindowFocus,
} = options
const isEnabled = enabled && (!params.isInstalledApp || !!params.appId) && !!params.conversationId
const isEnabled = enabled && (params.appSourceType !== AppSourceType.installedApp || !!params.appId) && !!params.conversationId
return useQuery<ConversationItem>({
queryKey: shareQueryKeys.conversationName(params),
queryFn: () => generationConversationName(params.isInstalledApp, params.appId, params.conversationId),
queryFn: () => generationConversationName(params.appSourceType, params.appId, params.conversationId),
enabled: isEnabled,
refetchOnReconnect,
refetchOnWindowFocus,

View File

@ -0,0 +1,44 @@
import type { DataSetListResponse } from '@/models/datasets'
import { useQuery } from '@tanstack/react-query'
import { consoleQuery } from '@/service/client'
import { fetchTryAppDatasets, fetchTryAppFlowPreview, fetchTryAppInfo, fetchTryAppParams } from './try-app'
export const useGetTryAppInfo = (appId: string) => {
return useQuery({
queryKey: consoleQuery.trialApps.info.queryKey({ input: { params: { appId } } }),
queryFn: () => {
return fetchTryAppInfo(appId)
},
enabled: !!appId,
})
}
export const useGetTryAppParams = (appId: string) => {
return useQuery({
queryKey: consoleQuery.trialApps.parameters.queryKey({ input: { params: { appId } } }),
queryFn: () => {
return fetchTryAppParams(appId)
},
enabled: !!appId,
})
}
export const useGetTryAppDataSets = (appId: string, ids: string[]) => {
return useQuery<DataSetListResponse>({
queryKey: consoleQuery.trialApps.datasets.queryKey({ input: { params: { appId }, query: { ids } } }),
queryFn: () => {
return fetchTryAppDatasets(appId, ids)
},
enabled: ids.length > 0,
})
}
export const useGetTryAppFlowPreview = (appId: string, disabled?: boolean) => {
return useQuery({
queryKey: consoleQuery.trialApps.workflows.queryKey({ input: { params: { appId } } }),
enabled: !disabled,
queryFn: () => {
return fetchTryAppFlowPreview(appId)
},
})
}