mirror of
https://github.com/langgenius/dify.git
synced 2025-12-22 15:27:32 +00:00
Compare commits
4 Commits
feature/tr
...
refactor/u
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e1f571919 | ||
|
|
5446127705 | ||
|
|
d77837e800 | ||
|
|
27e5abc39b |
@@ -2,7 +2,6 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useSWR from 'swr'
|
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { RiCalendarLine } from '@remixicon/react'
|
import { RiCalendarLine } from '@remixicon/react'
|
||||||
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
|
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
|
||||||
@@ -10,7 +9,7 @@ import type { QueryParam } from './index'
|
|||||||
import Chip from '@/app/components/base/chip'
|
import Chip from '@/app/components/base/chip'
|
||||||
import Input from '@/app/components/base/input'
|
import Input from '@/app/components/base/input'
|
||||||
import Sort from '@/app/components/base/sort'
|
import Sort from '@/app/components/base/sort'
|
||||||
import { fetchAnnotationsCount } from '@/service/log'
|
import { useAnnotationsCount } from '@/service/use-log'
|
||||||
dayjs.extend(quarterOfYear)
|
dayjs.extend(quarterOfYear)
|
||||||
|
|
||||||
const today = dayjs()
|
const today = dayjs()
|
||||||
@@ -35,7 +34,7 @@ type IFilterProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Filter: FC<IFilterProps> = ({ isChatMode, appId, queryParams, setQueryParams }: IFilterProps) => {
|
const Filter: FC<IFilterProps> = ({ isChatMode, appId, queryParams, setQueryParams }: IFilterProps) => {
|
||||||
const { data } = useSWR({ url: `/apps/${appId}/annotations/count` }, fetchAnnotationsCount)
|
const { data } = useAnnotationsCount(appId)
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
if (!data)
|
if (!data)
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import useSWR from 'swr'
|
|
||||||
import { useDebounce } from 'ahooks'
|
import { useDebounce } from 'ahooks'
|
||||||
import { omit } from 'lodash-es'
|
import { omit } from 'lodash-es'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
@@ -12,10 +11,11 @@ import Filter, { TIME_PERIOD_MAPPING } from './filter'
|
|||||||
import EmptyElement from './empty-element'
|
import EmptyElement from './empty-element'
|
||||||
import Pagination from '@/app/components/base/pagination'
|
import Pagination from '@/app/components/base/pagination'
|
||||||
import Loading from '@/app/components/base/loading'
|
import Loading from '@/app/components/base/loading'
|
||||||
import { fetchChatConversations, fetchCompletionConversations } from '@/service/log'
|
import { useChatConversations, useCompletionConversations } from '@/service/use-log'
|
||||||
import { APP_PAGE_LIMIT } from '@/config'
|
import { APP_PAGE_LIMIT } from '@/config'
|
||||||
import type { App } from '@/types/app'
|
import type { App } from '@/types/app'
|
||||||
import { AppModeEnum } from '@/types/app'
|
import { AppModeEnum } from '@/types/app'
|
||||||
|
import type { ChatConversationsRequest, CompletionConversationsRequest } from '@/models/log'
|
||||||
export type ILogsProps = {
|
export type ILogsProps = {
|
||||||
appDetail: App
|
appDetail: App
|
||||||
}
|
}
|
||||||
@@ -71,37 +71,43 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
|
|||||||
|
|
||||||
// Get the app type first
|
// Get the app type first
|
||||||
const isChatMode = appDetail.mode !== AppModeEnum.COMPLETION
|
const isChatMode = appDetail.mode !== AppModeEnum.COMPLETION
|
||||||
|
const { sort_by } = debouncedQueryParams
|
||||||
|
|
||||||
const query = {
|
const completionQuery = useMemo<CompletionConversationsRequest & { sort_by?: string }>(() => ({
|
||||||
page: currPage + 1,
|
page: currPage + 1,
|
||||||
limit,
|
limit,
|
||||||
...((debouncedQueryParams.period !== '9')
|
keyword: debouncedQueryParams.keyword ?? '',
|
||||||
? {
|
annotation_status: debouncedQueryParams.annotation_status ?? 'all',
|
||||||
start: dayjs().subtract(TIME_PERIOD_MAPPING[debouncedQueryParams.period].value, 'day').startOf('day').format('YYYY-MM-DD HH:mm'),
|
start: debouncedQueryParams.period !== '9'
|
||||||
end: dayjs().endOf('day').format('YYYY-MM-DD HH:mm'),
|
? dayjs().subtract(TIME_PERIOD_MAPPING[debouncedQueryParams.period].value, 'day').startOf('day').format('YYYY-MM-DD HH:mm')
|
||||||
}
|
: '',
|
||||||
: {}),
|
end: debouncedQueryParams.period !== '9'
|
||||||
...(isChatMode ? { sort_by: debouncedQueryParams.sort_by } : {}),
|
? dayjs().endOf('day').format('YYYY-MM-DD HH:mm')
|
||||||
...omit(debouncedQueryParams, ['period']),
|
: '',
|
||||||
}
|
...omit(debouncedQueryParams, ['period', 'sort_by', 'keyword', 'annotation_status']),
|
||||||
|
}), [currPage, debouncedQueryParams, limit])
|
||||||
|
|
||||||
|
const chatQuery = useMemo<ChatConversationsRequest & { sort_by?: string }>(() => ({
|
||||||
|
...completionQuery,
|
||||||
|
sort_by,
|
||||||
|
message_count: 0,
|
||||||
|
}), [completionQuery, sort_by])
|
||||||
|
|
||||||
// When the details are obtained, proceed to the next request
|
// When the details are obtained, proceed to the next request
|
||||||
const { data: chatConversations, mutate: mutateChatList } = useSWR(() => isChatMode
|
const { data: chatConversations, refetch: refetchChatList } = useChatConversations(appDetail.id, chatQuery, isChatMode)
|
||||||
? {
|
|
||||||
url: `/apps/${appDetail.id}/chat-conversations`,
|
|
||||||
params: query,
|
|
||||||
}
|
|
||||||
: null, fetchChatConversations)
|
|
||||||
|
|
||||||
const { data: completionConversations, mutate: mutateCompletionList } = useSWR(() => !isChatMode
|
const { data: completionConversations, refetch: refetchCompletionList } = useCompletionConversations(appDetail.id, completionQuery, !isChatMode)
|
||||||
? {
|
|
||||||
url: `/apps/${appDetail.id}/completion-conversations`,
|
|
||||||
params: query,
|
|
||||||
}
|
|
||||||
: null, fetchCompletionConversations)
|
|
||||||
|
|
||||||
const total = isChatMode ? chatConversations?.total : completionConversations?.total
|
const total = isChatMode ? chatConversations?.total : completionConversations?.total
|
||||||
|
|
||||||
|
const handleRefreshList = useCallback(() => {
|
||||||
|
if (isChatMode) {
|
||||||
|
void refetchChatList()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
void refetchCompletionList()
|
||||||
|
}, [isChatMode, refetchChatList, refetchCompletionList])
|
||||||
|
|
||||||
const handleQueryParamsChange = useCallback((next: QueryParam) => {
|
const handleQueryParamsChange = useCallback((next: QueryParam) => {
|
||||||
setCurrPage(0)
|
setCurrPage(0)
|
||||||
setQueryParams(next)
|
setQueryParams(next)
|
||||||
@@ -124,12 +130,13 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
|
|||||||
<p className='system-sm-regular shrink-0 text-text-tertiary'>{t('appLog.description')}</p>
|
<p className='system-sm-regular shrink-0 text-text-tertiary'>{t('appLog.description')}</p>
|
||||||
<div className='flex max-h-[calc(100%-16px)] flex-1 grow flex-col py-4'>
|
<div className='flex max-h-[calc(100%-16px)] flex-1 grow flex-col py-4'>
|
||||||
<Filter isChatMode={isChatMode} appId={appDetail.id} queryParams={queryParams} setQueryParams={handleQueryParamsChange} />
|
<Filter isChatMode={isChatMode} appId={appDetail.id} queryParams={queryParams} setQueryParams={handleQueryParamsChange} />
|
||||||
{total === undefined
|
{(() => {
|
||||||
? <Loading type='app' />
|
if (total === undefined)
|
||||||
: total > 0
|
return <Loading type='app' />
|
||||||
? <List logs={isChatMode ? chatConversations : completionConversations} appDetail={appDetail} onRefresh={isChatMode ? mutateChatList : mutateCompletionList} />
|
if (total > 0)
|
||||||
: <EmptyElement appDetail={appDetail} />
|
return <List logs={isChatMode ? chatConversations : completionConversations} appDetail={appDetail} onRefresh={handleRefreshList} />
|
||||||
}
|
return <EmptyElement appDetail={appDetail} />
|
||||||
|
})()}
|
||||||
{/* Show Pagination only if the total is more than the limit */}
|
{/* Show Pagination only if the total is more than the limit */}
|
||||||
{(total && total > APP_PAGE_LIMIT)
|
{(total && total > APP_PAGE_LIMIT)
|
||||||
? <Pagination
|
? <Pagination
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import useSWR from 'swr'
|
|
||||||
import {
|
import {
|
||||||
HandThumbDownIcon,
|
HandThumbDownIcon,
|
||||||
HandThumbUpIcon,
|
HandThumbUpIcon,
|
||||||
@@ -18,7 +17,7 @@ import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
|||||||
import type { ChatItemInTree } from '../../base/chat/types'
|
import type { ChatItemInTree } from '../../base/chat/types'
|
||||||
import Indicator from '../../header/indicator'
|
import Indicator from '../../header/indicator'
|
||||||
import VarPanel from './var-panel'
|
import VarPanel from './var-panel'
|
||||||
import type { FeedbackFunc, FeedbackType, IChatItem, SubmitAnnotationFunc } from '@/app/components/base/chat/chat/type'
|
import type { FeedbackFunc, IChatItem, SubmitAnnotationFunc } from '@/app/components/base/chat/chat/type'
|
||||||
import type { Annotation, ChatConversationGeneralDetail, ChatConversationsResponse, ChatMessage, ChatMessagesRequest, CompletionConversationGeneralDetail, CompletionConversationsResponse, LogAnnotation } from '@/models/log'
|
import type { Annotation, ChatConversationGeneralDetail, ChatConversationsResponse, ChatMessage, ChatMessagesRequest, CompletionConversationGeneralDetail, CompletionConversationsResponse, LogAnnotation } from '@/models/log'
|
||||||
import { type App, AppModeEnum } from '@/types/app'
|
import { type App, AppModeEnum } from '@/types/app'
|
||||||
import ActionButton from '@/app/components/base/action-button'
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
@@ -26,7 +25,8 @@ import Loading from '@/app/components/base/loading'
|
|||||||
import Drawer from '@/app/components/base/drawer'
|
import Drawer from '@/app/components/base/drawer'
|
||||||
import Chat from '@/app/components/base/chat/chat'
|
import Chat from '@/app/components/base/chat/chat'
|
||||||
import { ToastContext } from '@/app/components/base/toast'
|
import { ToastContext } from '@/app/components/base/toast'
|
||||||
import { fetchChatConversationDetail, fetchChatMessages, fetchCompletionConversationDetail, updateLogMessageAnnotations, updateLogMessageFeedbacks } from '@/service/log'
|
import { fetchChatMessages } from '@/service/log'
|
||||||
|
import { useChatConversationDetail, useCompletionConversationDetail, useUpdateLogMessageAnnotation, useUpdateLogMessageFeedback } from '@/service/use-log'
|
||||||
import ModelInfo from '@/app/components/app/log/model-info'
|
import ModelInfo from '@/app/components/app/log/model-info'
|
||||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||||
import TextGeneration from '@/app/components/app/text-generate/item'
|
import TextGeneration from '@/app/components/app/text-generate/item'
|
||||||
@@ -199,6 +199,39 @@ type IDetailPanel = {
|
|||||||
onSubmitAnnotation: SubmitAnnotationFunc
|
onSubmitAnnotation: SubmitAnnotationFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useConversationDetailActions = (appId: string | undefined, detailQueryKey: any) => {
|
||||||
|
const { notify } = useContext(ToastContext)
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const { mutateAsync: submitFeedback } = useUpdateLogMessageFeedback(appId, detailQueryKey)
|
||||||
|
const { mutateAsync: submitAnnotation } = useUpdateLogMessageAnnotation(appId, detailQueryKey)
|
||||||
|
|
||||||
|
const handleFeedback = useCallback<FeedbackFunc>(async (mid, { rating, content }) => {
|
||||||
|
try {
|
||||||
|
await submitFeedback({ mid, rating, content })
|
||||||
|
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}, [notify, submitFeedback, t])
|
||||||
|
|
||||||
|
const handleAnnotation = useCallback<SubmitAnnotationFunc>(async (mid, value) => {
|
||||||
|
try {
|
||||||
|
await submitAnnotation({ mid, value })
|
||||||
|
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}, [notify, submitAnnotation, t])
|
||||||
|
|
||||||
|
return { handleFeedback, handleAnnotation }
|
||||||
|
}
|
||||||
|
|
||||||
function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
||||||
const MIN_ITEMS_FOR_SCROLL_LOADING = 8
|
const MIN_ITEMS_FOR_SCROLL_LOADING = 8
|
||||||
const SCROLL_THRESHOLD_PX = 50
|
const SCROLL_THRESHOLD_PX = 50
|
||||||
@@ -369,7 +402,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
|||||||
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}, [allChatItems, appDetail?.id, t])
|
}, [allChatItems, appDetail?.id, notify, t])
|
||||||
|
|
||||||
const fetchInitiated = useRef(false)
|
const fetchInitiated = useRef(false)
|
||||||
|
|
||||||
@@ -516,7 +549,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
|||||||
finally {
|
finally {
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
}, [allChatItems, detail.id, hasMore, isLoading, timezone, t, appDetail])
|
}, [allChatItems, detail?.model_config?.configs?.introduction, detail.id, hasMore, isLoading, timezone, t, appDetail])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const scrollableDiv = document.getElementById('scrollableDiv')
|
const scrollableDiv = document.getElementById('scrollableDiv')
|
||||||
@@ -811,39 +844,8 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
|
|||||||
*/
|
*/
|
||||||
const CompletionConversationDetailComp: FC<{ appId?: string; conversationId?: string }> = ({ appId, conversationId }) => {
|
const CompletionConversationDetailComp: FC<{ appId?: string; conversationId?: string }> = ({ appId, conversationId }) => {
|
||||||
// Text Generator App Session Details Including Message List
|
// Text Generator App Session Details Including Message List
|
||||||
const detailParams = ({ url: `/apps/${appId}/completion-conversations/${conversationId}` })
|
const { data: conversationDetail, queryKey: detailQueryKey } = useCompletionConversationDetail(appId, conversationId)
|
||||||
const { data: conversationDetail, mutate: conversationDetailMutate } = useSWR(() => (appId && conversationId) ? detailParams : null, fetchCompletionConversationDetail)
|
const { handleFeedback, handleAnnotation } = useConversationDetailActions(appId, detailQueryKey)
|
||||||
const { notify } = useContext(ToastContext)
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const handleFeedback = async (mid: string, { rating, content }: FeedbackType): Promise<boolean> => {
|
|
||||||
try {
|
|
||||||
await updateLogMessageFeedbacks({
|
|
||||||
url: `/apps/${appId}/feedbacks`,
|
|
||||||
body: { message_id: mid, rating, content: content ?? undefined },
|
|
||||||
})
|
|
||||||
conversationDetailMutate()
|
|
||||||
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleAnnotation = async (mid: string, value: string): Promise<boolean> => {
|
|
||||||
try {
|
|
||||||
await updateLogMessageAnnotations({ url: `/apps/${appId}/annotations`, body: { message_id: mid, content: value } })
|
|
||||||
conversationDetailMutate()
|
|
||||||
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conversationDetail)
|
if (!conversationDetail)
|
||||||
return null
|
return null
|
||||||
@@ -859,37 +861,8 @@ const CompletionConversationDetailComp: FC<{ appId?: string; conversationId?: st
|
|||||||
* Chat App Conversation Detail Component
|
* Chat App Conversation Detail Component
|
||||||
*/
|
*/
|
||||||
const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string }> = ({ appId, conversationId }) => {
|
const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string }> = ({ appId, conversationId }) => {
|
||||||
const detailParams = { url: `/apps/${appId}/chat-conversations/${conversationId}` }
|
const { data: conversationDetail, queryKey: detailQueryKey } = useChatConversationDetail(appId, conversationId)
|
||||||
const { data: conversationDetail } = useSWR(() => (appId && conversationId) ? detailParams : null, fetchChatConversationDetail)
|
const { handleFeedback, handleAnnotation } = useConversationDetailActions(appId, detailQueryKey)
|
||||||
const { notify } = useContext(ToastContext)
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const handleFeedback = async (mid: string, { rating, content }: FeedbackType): Promise<boolean> => {
|
|
||||||
try {
|
|
||||||
await updateLogMessageFeedbacks({
|
|
||||||
url: `/apps/${appId}/feedbacks`,
|
|
||||||
body: { message_id: mid, rating, content: content ?? undefined },
|
|
||||||
})
|
|
||||||
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleAnnotation = async (mid: string, value: string): Promise<boolean> => {
|
|
||||||
try {
|
|
||||||
await updateLogMessageAnnotations({ url: `/apps/${appId}/annotations`, body: { message_id: mid, content: value } })
|
|
||||||
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conversationDetail)
|
if (!conversationDetail)
|
||||||
return null
|
return null
|
||||||
@@ -962,14 +935,12 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
|||||||
router.push(buildUrlWithConversation(log.id), { scroll: false })
|
router.push(buildUrlWithConversation(log.id), { scroll: false })
|
||||||
}, [buildUrlWithConversation, conversationIdInUrl, currentConversation, router, showDrawer])
|
}, [buildUrlWithConversation, conversationIdInUrl, currentConversation, router, showDrawer])
|
||||||
|
|
||||||
const currentConversationId = currentConversation?.id
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!conversationIdInUrl) {
|
if (!conversationIdInUrl) {
|
||||||
if (pendingConversationIdRef.current)
|
if (pendingConversationIdRef.current)
|
||||||
return
|
return
|
||||||
|
|
||||||
if (showDrawer || currentConversationId) {
|
if (showDrawer || currentConversation?.id) {
|
||||||
setShowDrawer(false)
|
setShowDrawer(false)
|
||||||
setCurrentConversation(undefined)
|
setCurrentConversation(undefined)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { Fetcher } from 'swr'
|
|
||||||
import { get, post } from './base'
|
import { get, post } from './base'
|
||||||
import type {
|
import type {
|
||||||
AgentLogDetailRequest,
|
AgentLogDetailRequest,
|
||||||
@@ -22,59 +21,33 @@ import type {
|
|||||||
} from '@/models/log'
|
} from '@/models/log'
|
||||||
import type { NodeTracingListResponse } from '@/types/workflow'
|
import type { NodeTracingListResponse } from '@/types/workflow'
|
||||||
|
|
||||||
export const fetchConversationList: Fetcher<ConversationListResponse, { name: string; appId: string; params?: Record<string, any> }> = ({ appId, params }) => {
|
export const fetchConversationList = ({ appId, params }: { name: string; appId: string; params?: Record<string, any> }): Promise<ConversationListResponse> => get<ConversationListResponse>(`/console/api/apps/${appId}/messages`, params)
|
||||||
return get<ConversationListResponse>(`/console/api/apps/${appId}/messages`, params)
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Text Generation Application) Session List
|
// (Text Generation Application) Session List
|
||||||
export const fetchCompletionConversations: Fetcher<CompletionConversationsResponse, { url: string; params?: CompletionConversationsRequest }> = ({ url, params }) => {
|
export const fetchCompletionConversations = ({ url, params }: { url: string; params?: Partial<CompletionConversationsRequest> & { sort_by?: string } }): Promise<CompletionConversationsResponse> => get<CompletionConversationsResponse>(url, { params })
|
||||||
return get<CompletionConversationsResponse>(url, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Text Generation Application) Session Detail
|
// (Text Generation Application) Session Detail
|
||||||
export const fetchCompletionConversationDetail: Fetcher<CompletionConversationFullDetailResponse, { url: string }> = ({ url }) => {
|
export const fetchCompletionConversationDetail = ({ url }: { url: string }): Promise<CompletionConversationFullDetailResponse> => get<CompletionConversationFullDetailResponse>(url, {})
|
||||||
return get<CompletionConversationFullDetailResponse>(url, {})
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Chat Application) Session List
|
// (Chat Application) Session List
|
||||||
export const fetchChatConversations: Fetcher<ChatConversationsResponse, { url: string; params?: ChatConversationsRequest }> = ({ url, params }) => {
|
export const fetchChatConversations = ({ url, params }: { url: string; params?: Partial<ChatConversationsRequest> & { sort_by?: string } }): Promise<ChatConversationsResponse> => get<ChatConversationsResponse>(url, { params })
|
||||||
return get<ChatConversationsResponse>(url, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Chat Application) Session Detail
|
// (Chat Application) Session Detail
|
||||||
export const fetchChatConversationDetail: Fetcher<ChatConversationFullDetailResponse, { url: string }> = ({ url }) => {
|
export const fetchChatConversationDetail = ({ url }: { url: string }): Promise<ChatConversationFullDetailResponse> => get<ChatConversationFullDetailResponse>(url, {})
|
||||||
return get<ChatConversationFullDetailResponse>(url, {})
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Chat Application) Message list in one session
|
// (Chat Application) Message list in one session
|
||||||
export const fetchChatMessages: Fetcher<ChatMessagesResponse, { url: string; params: ChatMessagesRequest }> = ({ url, params }) => {
|
export const fetchChatMessages = ({ url, params }: { url: string; params: ChatMessagesRequest }): Promise<ChatMessagesResponse> => get<ChatMessagesResponse>(url, { params })
|
||||||
return get<ChatMessagesResponse>(url, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
export const updateLogMessageFeedbacks: Fetcher<LogMessageFeedbacksResponse, { url: string; body: LogMessageFeedbacksRequest }> = ({ url, body }) => {
|
export const updateLogMessageFeedbacks = ({ url, body }: { url: string; body: LogMessageFeedbacksRequest }): Promise<LogMessageFeedbacksResponse> => post<LogMessageFeedbacksResponse>(url, { body })
|
||||||
return post<LogMessageFeedbacksResponse>(url, { body })
|
|
||||||
}
|
|
||||||
|
|
||||||
export const updateLogMessageAnnotations: Fetcher<LogMessageAnnotationsResponse, { url: string; body: LogMessageAnnotationsRequest }> = ({ url, body }) => {
|
export const updateLogMessageAnnotations = ({ url, body }: { url: string; body: LogMessageAnnotationsRequest }): Promise<LogMessageAnnotationsResponse> => post<LogMessageAnnotationsResponse>(url, { body })
|
||||||
return post<LogMessageAnnotationsResponse>(url, { body })
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetchAnnotationsCount: Fetcher<AnnotationsCountResponse, { url: string }> = ({ url }) => {
|
export const fetchAnnotationsCount = ({ url }: { url: string }): Promise<AnnotationsCountResponse> => get<AnnotationsCountResponse>(url)
|
||||||
return get<AnnotationsCountResponse>(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetchWorkflowLogs: Fetcher<WorkflowLogsResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
|
export const fetchWorkflowLogs = ({ url, params }: { url: string; params: Record<string, any> }): Promise<WorkflowLogsResponse> => get<WorkflowLogsResponse>(url, { params })
|
||||||
return get<WorkflowLogsResponse>(url, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetchRunDetail = (url: string) => {
|
export const fetchRunDetail = (url: string): Promise<WorkflowRunDetailResponse> => get<WorkflowRunDetailResponse>(url)
|
||||||
return get<WorkflowRunDetailResponse>(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetchTracingList: Fetcher<NodeTracingListResponse, { url: string }> = ({ url }) => {
|
export const fetchTracingList = ({ url }: { url: string }): Promise<NodeTracingListResponse> => get<NodeTracingListResponse>(url)
|
||||||
return get<NodeTracingListResponse>(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetchAgentLogDetail = ({ appID, params }: { appID: string; params: AgentLogDetailRequest }) => {
|
export const fetchAgentLogDetail = ({ appID, params }: { appID: string; params: AgentLogDetailRequest }): Promise<AgentLogDetailResponse> => get<AgentLogDetailResponse>(`/apps/${appID}/agent/logs`, { params })
|
||||||
return get<AgentLogDetailResponse>(`/apps/${appID}/agent/logs`, { params })
|
|
||||||
}
|
|
||||||
|
|||||||
140
web/service/use-log.ts
Normal file
140
web/service/use-log.ts
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import type { QueryKey } from '@tanstack/react-query'
|
||||||
|
import {
|
||||||
|
useMutation,
|
||||||
|
useQuery,
|
||||||
|
useQueryClient,
|
||||||
|
} from '@tanstack/react-query'
|
||||||
|
import {
|
||||||
|
fetchAnnotationsCount,
|
||||||
|
fetchChatConversationDetail,
|
||||||
|
fetchChatConversations,
|
||||||
|
fetchCompletionConversationDetail,
|
||||||
|
fetchCompletionConversations,
|
||||||
|
updateLogMessageAnnotations,
|
||||||
|
updateLogMessageFeedbacks,
|
||||||
|
} from '@/service/log'
|
||||||
|
import type {
|
||||||
|
AnnotationsCountResponse,
|
||||||
|
ChatConversationFullDetailResponse,
|
||||||
|
ChatConversationsRequest,
|
||||||
|
ChatConversationsResponse,
|
||||||
|
CompletionConversationFullDetailResponse,
|
||||||
|
CompletionConversationsRequest,
|
||||||
|
CompletionConversationsResponse,
|
||||||
|
MessageRating,
|
||||||
|
} from '@/models/log'
|
||||||
|
|
||||||
|
type FeedbackPayload = {
|
||||||
|
mid: string
|
||||||
|
rating: MessageRating
|
||||||
|
content?: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
type AnnotationPayload = {
|
||||||
|
mid: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatConversationsParams = Partial<ChatConversationsRequest> & { sort_by?: string }
|
||||||
|
type CompletionConversationsParams = Partial<CompletionConversationsRequest> & { sort_by?: string }
|
||||||
|
|
||||||
|
export const chatConversationsKey = (appId?: string, params?: ChatConversationsParams): QueryKey => ['chat-conversations', appId, params]
|
||||||
|
export const completionConversationsKey = (appId?: string, params?: CompletionConversationsParams): QueryKey => ['completion-conversations', appId, params]
|
||||||
|
export const completionConversationDetailKey = (appId?: string, conversationId?: string): QueryKey => ['completion-conversation-detail', appId, conversationId]
|
||||||
|
|
||||||
|
export const chatConversationDetailKey = (appId?: string, conversationId?: string): QueryKey => ['chat-conversation-detail', appId, conversationId]
|
||||||
|
|
||||||
|
export const annotationsCountKey = (appId?: string): QueryKey => ['annotations-count', appId]
|
||||||
|
|
||||||
|
export const useChatConversations = (appId?: string, params?: ChatConversationsParams, enabled = true) => {
|
||||||
|
const queryKey = chatConversationsKey(appId, params)
|
||||||
|
const queryResult = useQuery<ChatConversationsResponse>({
|
||||||
|
queryKey,
|
||||||
|
queryFn: () => fetchChatConversations({ url: `/apps/${appId}/chat-conversations`, params }),
|
||||||
|
enabled: Boolean(appId && enabled),
|
||||||
|
})
|
||||||
|
|
||||||
|
return { ...queryResult, queryKey }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useCompletionConversations = (appId?: string, params?: CompletionConversationsParams, enabled = true) => {
|
||||||
|
const queryKey = completionConversationsKey(appId, params)
|
||||||
|
const queryResult = useQuery<CompletionConversationsResponse>({
|
||||||
|
queryKey,
|
||||||
|
queryFn: () => fetchCompletionConversations({ url: `/apps/${appId}/completion-conversations`, params }),
|
||||||
|
enabled: Boolean(appId && enabled),
|
||||||
|
})
|
||||||
|
|
||||||
|
return { ...queryResult, queryKey }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAnnotationsCount = (appId?: string) => {
|
||||||
|
const queryKey = annotationsCountKey(appId)
|
||||||
|
const queryResult = useQuery<AnnotationsCountResponse>({
|
||||||
|
queryKey,
|
||||||
|
queryFn: () => fetchAnnotationsCount({ url: `/apps/${appId}/annotations/count` }),
|
||||||
|
enabled: Boolean(appId),
|
||||||
|
})
|
||||||
|
|
||||||
|
return { ...queryResult, queryKey }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useCompletionConversationDetail = (appId?: string, conversationId?: string) => {
|
||||||
|
const queryKey = completionConversationDetailKey(appId, conversationId)
|
||||||
|
const queryResult = useQuery<CompletionConversationFullDetailResponse>({
|
||||||
|
queryKey,
|
||||||
|
queryFn: () => fetchCompletionConversationDetail({ url: `/apps/${appId}/completion-conversations/${conversationId}` }),
|
||||||
|
enabled: Boolean(appId && conversationId),
|
||||||
|
})
|
||||||
|
|
||||||
|
return { ...queryResult, queryKey }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useChatConversationDetail = (appId?: string, conversationId?: string) => {
|
||||||
|
const queryKey = chatConversationDetailKey(appId, conversationId)
|
||||||
|
const queryResult = useQuery<ChatConversationFullDetailResponse>({
|
||||||
|
queryKey,
|
||||||
|
queryFn: () => fetchChatConversationDetail({ url: `/apps/${appId}/chat-conversations/${conversationId}` }),
|
||||||
|
enabled: Boolean(appId && conversationId),
|
||||||
|
})
|
||||||
|
|
||||||
|
return { ...queryResult, queryKey }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useUpdateLogMessageFeedback = (appId?: string, invalidateKey?: QueryKey) => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ mid, rating, content }: FeedbackPayload) => {
|
||||||
|
if (!appId)
|
||||||
|
throw new Error('appId is required to update message feedback.')
|
||||||
|
return await updateLogMessageFeedbacks({
|
||||||
|
url: `/apps/${appId}/feedbacks`,
|
||||||
|
body: { message_id: mid, rating, content: content ?? undefined },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
if (invalidateKey)
|
||||||
|
queryClient.invalidateQueries({ queryKey: invalidateKey })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useUpdateLogMessageAnnotation = (appId?: string, invalidateKey?: QueryKey) => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ mid, value }: AnnotationPayload) => {
|
||||||
|
if (!appId)
|
||||||
|
throw new Error('appId is required to update message annotation.')
|
||||||
|
return await updateLogMessageAnnotations({
|
||||||
|
url: `/apps/${appId}/annotations`,
|
||||||
|
body: { message_id: mid, content: value },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
if (invalidateKey)
|
||||||
|
queryClient.invalidateQueries({ queryKey: invalidateKey })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user