Commit 90ee7fe2 authored by JzoNg's avatar JzoNg

tracing

parent bc90fc88
......@@ -18,7 +18,7 @@ const DetailPanel: FC<ILogDetail> = ({ runID, onClose }) => {
<XClose className='w-4 h-4 text-gray-500' />
</span>
<h1 className='shrink-0 px-4 py-1 text-md font-semibold text-gray-900'>{t('appLog.runDetail.workflowTitle')}</h1>
<Run activeTab='TRACING' runID={runID}/>
<Run runID={runID}/>
</div>
)
}
......
......@@ -5,14 +5,13 @@ import { useTranslation } from 'react-i18next'
import cn from 'classnames'
import Result from './result'
import Tracing from './tracing'
// import type { App } from '@/types/app'
type RunProps = {
activeTab: 'RESULT' | 'TRACING'
activeTab?: 'RESULT' | 'TRACING'
runID: string
}
const RunPanel: FC<RunProps> = ({ activeTab, runID }) => {
const RunPanel: FC<RunProps> = ({ activeTab = 'RESULT', runID }) => {
const { t } = useTranslation()
const [currentTab, setCurrentTab] = useState<string>(activeTab)
......
......@@ -3,24 +3,15 @@ import { useTranslation } from 'react-i18next'
import type { FC } from 'react'
import cn from 'classnames'
import BlockIcon from '../block-icon'
import type { BlockEnum } from '../types'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import { AlertCircle, AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import { CheckCircle, Loading02 } from '@/app/components/base/icons/src/vender/line/general'
import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows'
export type NodeInfo = {
type: BlockEnum
title: string
time: number
tokens: number
status: string
error?: string
}
import type { NodeTracing } from '@/types/workflow'
type Props = {
nodeInfo: NodeInfo
nodeInfo: NodeTracing
collapsed: boolean
collapseHandle: () => void
}
......@@ -60,9 +51,9 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => {
!collapsed && 'rotate-90',
)}
/>
<BlockIcon className='shrink-0 mr-2' type={nodeInfo.type} />
<BlockIcon className='shrink-0 mr-2' type={nodeInfo.node_type} />
<div className='grow text-gray-700 text-[13px] leading-[16px] font-semibold truncate' title={nodeInfo.title}>{nodeInfo.title}</div>
<div className='shrink-0 text-gray-500 text-xs leading-[18px]'>{`${getTime(nodeInfo.time)} · ${getTokenCount(nodeInfo.tokens)} tokens`}</div>
<div className='shrink-0 text-gray-500 text-xs leading-[18px]'>{`${getTime(nodeInfo.elapsed_time)} · ${getTokenCount(nodeInfo.execution_metadata.total_tokens)} tokens`}</div>
{nodeInfo.status === 'succeeded' && (
<CheckCircle className='shrink-0 ml-2 w-3.5 h-3.5 text-[#12B76A]' />
)}
......
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
// import { useTranslation } from 'react-i18next'
// import cn from 'classnames'
import { BlockEnum } from '../types'
import React, { useCallback, useEffect, useState } from 'react'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import NodePanel from './node'
import Loading from '@/app/components/base/loading'
import { fetchTracingList } from '@/service/log'
import { useStore as useAppStore } from '@/app/components/app/store'
import type { NodeTracing } from '@/types/workflow'
import { ToastContext } from '@/app/components/base/toast'
type TracingProps = {
runID: string
}
const nodeInfoFake = {
type: BlockEnum.Start,
title: 'START',
time: 67.349,
tokens: 2708,
status: 'failed',
error: 'lvlvlvlv',
}
const Tracing: FC<TracingProps> = ({ runID }) => {
// const { t } = useTranslation()
const [nodeCollapsed, setCurrentTab] = useState<boolean>(false)
const { notify } = useContext(ToastContext)
const { appDetail } = useAppStore()
const [loading, setLoading] = useState<boolean>(true)
const [list, setList] = useState<NodeTracing[]>([])
const [collapseState, setCollapseState] = useState<boolean[]>([])
const getTracingList = useCallback(async (appID: string, runID: string) => {
setLoading(true)
try {
const { data: nodeList } = await fetchTracingList({
url: `/apps/${appID}/workflow-runs/${runID}/node-executions`,
})
const collapseState = nodeList.map(node => node.status === 'succeeded')
setList(nodeList)
setCollapseState(collapseState)
setLoading(false)
}
catch (err) {
notify({
type: 'error',
message: `${err}`,
})
setLoading(false)
}
}, [notify])
useEffect(() => {
if (appDetail && runID)
getTracingList(appDetail.id, runID)
}, [appDetail, getTracingList, runID])
const collapseStateChange = () => {
setCurrentTab(!nodeCollapsed)
const collapseStateChange = (index: number) => {
const newCollapseState = produce(collapseState, (draft: boolean[]) => {
draft[index] = !draft[index]
})
setCollapseState(newCollapseState)
}
if (loading) {
return (
<div className='flex h-full items-center justify-center bg-white'>
<Loading />
</div>
)
}
return (
<div className='bg-gray-50 py-2'>
<NodePanel nodeInfo={nodeInfoFake} collapsed={nodeCollapsed} collapseHandle={collapseStateChange} />
{list.map((node, index) => (
<NodePanel
key={node.id}
nodeInfo={node}
collapsed={collapseState[index]}
collapseHandle={() => collapseStateChange(index)}
/>
))}
</div>
)
}
......
......@@ -19,6 +19,7 @@ import type {
WorkflowLogsResponse,
WorkflowRunDetailResponse,
} from '@/models/log'
import type { NodeTracingListResponse } from '@/types/workflow'
export const fetchConversationList: Fetcher<ConversationListResponse, { name: string; appId: string; params?: Record<string, any> }> = ({ appId, params }) => {
return get<ConversationListResponse>(`/console/api/apps/${appId}/messages`, params)
......@@ -68,3 +69,7 @@ export const fetchWorkflowLogs: Fetcher<WorkflowLogsResponse, { url: string; par
export const fetchRunDetail = ({ appID, runID }: { appID: string; runID: string }) => {
return get<WorkflowRunDetailResponse>(`/apps/${appID}/workflow-run/${runID}`)
}
export const fetchTracingList: Fetcher<NodeTracingListResponse, { url: string }> = ({ url }) => {
return get<NodeTracingListResponse>(url)
}
import type { Viewport } from 'reactflow'
import type {
BlockEnum,
Edge,
Node,
} from '@/app/components/workflow/types'
export type NodeTracing = {
id: string
index: number
predecessor_node_id: string
node_id: string
node_type: BlockEnum
title: string
inputs: any
process_data: any
outputs?: any
status: string
error?: string
elapsed_time: number
execution_metadata: {
total_tokens: number
total_price: number
currency: string
}
created_at: number
created_by: {
id: string
name: string
email: string
}
finished_at: number
}
export type FetchWorkflowDraftResponse = {
id: string
graph: {
......@@ -14,3 +42,7 @@ export type FetchWorkflowDraftResponse = {
features?: any
updated_at: number
}
export type NodeTracingListResponse = {
data: NodeTracing[]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment