run & tracing

This commit is contained in:
zxhlyh 2025-05-29 14:31:00 +08:00
parent 9176790adf
commit 1c2c4b62f8
12 changed files with 92 additions and 27 deletions

View File

@ -3,6 +3,7 @@ import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { RiCloseLine } from '@remixicon/react'
import Run from '@/app/components/workflow/run'
import { useStore } from '@/app/components/app/store'
type ILogDetail = {
runID: string
@ -11,6 +12,7 @@ type ILogDetail = {
const DetailPanel: FC<ILogDetail> = ({ runID, onClose }) => {
const { t } = useTranslation()
const appDetail = useStore(state => state.appDetail)
return (
<div className='relative flex grow flex-col pt-3'>
@ -18,7 +20,10 @@ const DetailPanel: FC<ILogDetail> = ({ runID, onClose }) => {
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
</span>
<h1 className='system-xl-semibold shrink-0 px-4 py-1 text-text-primary'>{t('appLog.runDetail.workflowTitle')}</h1>
<Run runID={runID}/>
<Run
runDetailUrl={`/apps/${appDetail?.id}/workflow-runs/${runID}`}
tracingListUrl={`/apps/${appDetail?.id}/workflow-runs/${runID}/node-executions`}
/>
</div>
)
}

View File

@ -6,6 +6,7 @@ import { RiCloseLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import type { IChatItem } from '@/app/components/base/chat/chat/type'
import Run from '@/app/components/workflow/run'
import { useStore } from '@/app/components/app/store'
type MessageLogModalProps = {
currentLogItem?: IChatItem
@ -24,6 +25,7 @@ const MessageLogModal: FC<MessageLogModalProps> = ({
const { t } = useTranslation()
const ref = useRef(null)
const [mounted, setMounted] = useState(false)
const appDetail = useStore(state => state.appDetail)
useClickAway(() => {
if (mounted)
@ -62,7 +64,8 @@ const MessageLogModal: FC<MessageLogModalProps> = ({
<Run
hideResult
activeTab={defaultTab as any}
runID={currentLogItem.workflow_run_id}
runDetailUrl={`/apps/${appDetail?.id}/workflow-runs/${currentLogItem.workflow_run_id}`}
tracingListUrl={`/apps/${appDetail?.id}/workflow-runs/${currentLogItem.workflow_run_id}/node-executions`}
/>
</div>
)

View File

@ -6,6 +6,7 @@ import type { WorkflowProps } from '@/app/components/workflow'
import RagPipelineChildren from './rag-pipeline-children'
import {
useAvailableNodesMetaData,
useGetRunAndTraceUrl,
useNodesSyncDraft,
usePipelineRefreshDraft,
usePipelineRun,
@ -35,6 +36,7 @@ const RagPipelineMain = ({
handleWorkflowStartRunInWorkflow,
} = usePipelineStartRun()
const availableNodesMetaData = useAvailableNodesMetaData()
const { getWorkflowRunAndTraceUrl } = useGetRunAndTraceUrl()
const hooksStore = useMemo(() => {
return {
@ -49,6 +51,7 @@ const RagPipelineMain = ({
handleStopRun,
handleStartWorkflowRun,
handleWorkflowStartRunInWorkflow,
getWorkflowRunAndTraceUrl,
}
}, [
availableNodesMetaData,
@ -62,6 +65,7 @@ const RagPipelineMain = ({
handleStopRun,
handleStartWorkflowRun,
handleWorkflowStartRunInWorkflow,
getWorkflowRunAndTraceUrl,
])
return (

View File

@ -4,3 +4,4 @@ export * from './use-nodes-sync-draft'
export * from './use-pipeline-run'
export * from './use-pipeline-start-run'
export * from './use-pipeline-init'
export * from './use-get-run-and-trace-url'

View File

@ -0,0 +1,18 @@
import { useCallback } from 'react'
import { useWorkflowStore } from '@/app/components/workflow/store'
export const useGetRunAndTraceUrl = () => {
const workflowStore = useWorkflowStore()
const getWorkflowRunAndTraceUrl = useCallback((runId: string) => {
const { pipelineId } = workflowStore.getState()
return {
runUrl: `/rag/pipelines/${pipelineId}/workflow-runs/${runId}`,
traceUrl: `/rag/pipelines/${pipelineId}/workflow-runs/${runId}/node-executions`,
}
}, [workflowStore])
return {
getWorkflowRunAndTraceUrl,
}
}

View File

@ -8,6 +8,7 @@ import type { WorkflowProps } from '@/app/components/workflow'
import WorkflowChildren from './workflow-children'
import {
useAvailableNodesMetaData,
useGetRunAndTraceUrl,
useNodesSyncDraft,
useWorkflowRefreshDraft,
useWorkflowRun,
@ -48,6 +49,7 @@ const WorkflowMain = ({
handleWorkflowStartRunInWorkflow,
} = useWorkflowStartRun()
const availableNodesMetaData = useAvailableNodesMetaData()
const { getWorkflowRunAndTraceUrl } = useGetRunAndTraceUrl()
const hooksStore = useMemo(() => {
return {
@ -63,6 +65,7 @@ const WorkflowMain = ({
handleWorkflowStartRunInChatflow,
handleWorkflowStartRunInWorkflow,
availableNodesMetaData,
getWorkflowRunAndTraceUrl,
}
}, [
syncWorkflowDraftWhenPageClose,
@ -77,6 +80,7 @@ const WorkflowMain = ({
handleWorkflowStartRunInChatflow,
handleWorkflowStartRunInWorkflow,
availableNodesMetaData,
getWorkflowRunAndTraceUrl,
])
return (

View File

@ -6,3 +6,4 @@ export * from './use-workflow-start-run'
export * from './use-is-chat-mode'
export * from './use-available-nodes-meta-data'
export * from './use-workflow-refresh-draft'
export * from './use-get-run-and-trace-url'

View File

@ -0,0 +1,18 @@
import { useCallback } from 'react'
import { useWorkflowStore } from '@/app/components/workflow/store'
export const useGetRunAndTraceUrl = () => {
const workflowStore = useWorkflowStore()
const getWorkflowRunAndTraceUrl = useCallback((runId: string) => {
const { appId } = workflowStore.getState()
return {
runUrl: `/apps/${appId}/workflow-runs/${runId}`,
traceUrl: `/apps/${appId}/workflow-runs/${runId}/node-executions`,
}
}, [workflowStore])
return {
getWorkflowRunAndTraceUrl,
}
}

View File

@ -36,6 +36,7 @@ export type CommonHooksFnMap = {
handleWorkflowStartRunInWorkflow: () => void
handleWorkflowStartRunInChatflow: () => void
availableNodesMetaData?: AvailableNodesMetaData
getWorkflowRunAndTraceUrl: (runId?: string) => { runUrl: string; traceUrl: string }
}
export type Shape = {
@ -57,6 +58,10 @@ export const createHooksStore = ({
availableNodesMetaData = {
nodes: [],
},
getWorkflowRunAndTraceUrl = () => ({
runUrl: '',
traceUrl: '',
}),
}: Partial<Shape>) => {
return createStore<Shape>(set => ({
refreshAll: props => set(state => ({ ...state, ...props })),
@ -72,6 +77,7 @@ export const createHooksStore = ({
handleWorkflowStartRunInWorkflow,
handleWorkflowStartRunInChatflow,
availableNodesMetaData,
getWorkflowRunAndTraceUrl,
}))
}

View File

@ -3,10 +3,12 @@ import type { WorkflowDataUpdater } from '../types'
import Run from '../run'
import { useStore } from '../store'
import { useWorkflowUpdate } from '../hooks'
import { useHooksStore } from '../hooks-store'
const Record = () => {
const historyWorkflowData = useStore(s => s.historyWorkflowData)
const { handleUpdateWorkflowCanvas } = useWorkflowUpdate()
const getWorkflowRunAndTraceUrl = useHooksStore(s => s.getWorkflowRunAndTraceUrl)
const handleResultCallback = useCallback((res: any) => {
const graph: WorkflowDataUpdater = res.graph
@ -23,7 +25,8 @@ const Record = () => {
{`Test Run#${historyWorkflowData?.sequence_number}`}
</div>
<Run
runID={historyWorkflowData?.id || ''}
runDetailUrl={getWorkflowRunAndTraceUrl(historyWorkflowData?.id).runUrl}
tracingListUrl={getWorkflowRunAndTraceUrl(historyWorkflowData?.id).traceUrl}
getResultCallback={handleResultCallback}
/>
</div>

View File

@ -12,19 +12,24 @@ import Loading from '@/app/components/base/loading'
import { fetchRunDetail, fetchTracingList } from '@/service/log'
import type { NodeTracing } from '@/types/workflow'
import type { WorkflowRunDetailResponse } from '@/models/log'
import { useStore as useAppStore } from '@/app/components/app/store'
export type RunProps = {
hideResult?: boolean
activeTab?: 'RESULT' | 'DETAIL' | 'TRACING'
runID: string
getResultCallback?: (result: WorkflowRunDetailResponse) => void
runDetailUrl: string
tracingListUrl: string
}
const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getResultCallback }) => {
const RunPanel: FC<RunProps> = ({
hideResult,
activeTab = 'RESULT',
getResultCallback,
runDetailUrl,
tracingListUrl,
}) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const [currentTab, setCurrentTab] = useState<string>(activeTab)
const appDetail = useAppStore(state => state.appDetail)
const [loading, setLoading] = useState<boolean>(true)
const [runDetail, setRunDetail] = useState<WorkflowRunDetailResponse>()
const [list, setList] = useState<NodeTracing[]>([])
@ -37,12 +42,9 @@ const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getRe
return 'N/A'
}, [runDetail])
const getResult = useCallback(async (appID: string, runID: string) => {
const getResult = useCallback(async () => {
try {
const res = await fetchRunDetail({
appID,
runID,
})
const res = await fetchRunDetail(runDetailUrl)
setRunDetail(res)
if (getResultCallback)
getResultCallback(res)
@ -53,12 +55,12 @@ const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getRe
message: `${err}`,
})
}
}, [notify, getResultCallback])
}, [notify, getResultCallback, runDetailUrl])
const getTracingList = useCallback(async (appID: string, runID: string) => {
const getTracingList = useCallback(async () => {
try {
const { data: nodeList } = await fetchTracingList({
url: `/apps/${appID}/workflow-runs/${runID}/node-executions`,
url: tracingListUrl,
})
setList(nodeList)
}
@ -68,27 +70,27 @@ const RunPanel: FC<RunProps> = ({ hideResult, activeTab = 'RESULT', runID, getRe
message: `${err}`,
})
}
}, [notify])
}, [notify, tracingListUrl])
const getData = async (appID: string, runID: string) => {
const getData = useCallback(async () => {
setLoading(true)
await getResult(appID, runID)
await getTracingList(appID, runID)
await getResult()
await getTracingList()
setLoading(false)
}
}, [getResult, getTracingList])
const switchTab = async (tab: string) => {
setCurrentTab(tab)
if (tab === 'RESULT')
appDetail?.id && await getResult(appDetail.id, runID)
appDetail?.id && await getTracingList(appDetail.id, runID)
runDetailUrl && await getResult()
tracingListUrl && await getTracingList()
}
useEffect(() => {
// fetch data
if (appDetail && runID)
getData(appDetail.id, runID)
}, [appDetail, runID])
if (runDetailUrl && tracingListUrl)
getData()
}, [getData, runDetailUrl, tracingListUrl])
const [height, setHeight] = useState(0)
const ref = useRef<HTMLDivElement>(null)

View File

@ -67,8 +67,8 @@ export const fetchWorkflowLogs: Fetcher<WorkflowLogsResponse, { url: string; par
return get<WorkflowLogsResponse>(url, { params })
}
export const fetchRunDetail = ({ appID, runID }: { appID: string; runID: string }) => {
return get<WorkflowRunDetailResponse>(`/apps/${appID}/workflow-runs/${runID}`)
export const fetchRunDetail = (url: string) => {
return get<WorkflowRunDetailResponse>(url)
}
export const fetchTracingList: Fetcher<NodeTracingListResponse, { url: string }> = ({ url }) => {