Commit 294128d4 authored by JzoNg's avatar JzoNg

fix tracing

parent e5cf4ea6
...@@ -876,9 +876,10 @@ export const useWorkflowRun = () => { ...@@ -876,9 +876,10 @@ export const useWorkflowRun = () => {
body: params, body: params,
}, },
{ {
onWorkflowStarted: ({ task_id, workflow_run_id }) => { onWorkflowStarted: ({ task_id, workflow_run_id, sequence_number }) => {
useStore.setState({ runningStatus: WorkflowRunningStatus.Running }) useStore.setState({ runningStatus: WorkflowRunningStatus.Running })
useStore.setState({ taskId: task_id }) useStore.setState({ taskId: task_id })
useStore.setState({ currentSequenceNumber: sequence_number })
useStore.setState({ workflowRunId: workflow_run_id }) useStore.setState({ workflowRunId: workflow_run_id })
const newNodes = produce(getNodes(), (draft) => { const newNodes = produce(getNodes(), (draft) => {
draft.forEach((node) => { draft.forEach((node) => {
......
...@@ -4,14 +4,17 @@ import { useStore } from '../store' ...@@ -4,14 +4,17 @@ import { useStore } from '../store'
import { XClose } from '@/app/components/base/icons/src/vender/line/general' import { XClose } from '@/app/components/base/icons/src/vender/line/general'
const Record = () => { const Record = () => {
const { workflowRunId, setWorkflowRunId } = useStore() const { currentSequenceNumber, setCurrentSequenceNumber, workflowRunId, setWorkflowRunId } = useStore()
return ( return (
<div className='flex flex-col w-[400px] h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white'> <div className='flex flex-col w-[400px] h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white'>
<div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-gray-900'> <div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-gray-900'>
Test Run#5 {`Test Run#${currentSequenceNumber}`}
<div <div
className='flex items-center justify-center w-6 h-6 cursor-pointer' className='flex items-center justify-center w-6 h-6 cursor-pointer'
onClick={() => setWorkflowRunId('')} onClick={() => {
setWorkflowRunId('')
setCurrentSequenceNumber(0)
}}
> >
<XClose className='w-4 h-4 text-gray-500' /> <XClose className='w-4 h-4 text-gray-500' />
</div> </div>
......
...@@ -48,7 +48,11 @@ const RunHistory = () => { ...@@ -48,7 +48,11 @@ const RunHistory = () => {
'flex mb-0.5 px-2 py-[7px] rounded-lg hover:bg-primary-50 cursor-pointer', 'flex mb-0.5 px-2 py-[7px] rounded-lg hover:bg-primary-50 cursor-pointer',
item.id === workflowRunId && 'bg-primary-50', item.id === workflowRunId && 'bg-primary-50',
)} )}
onClick={() => useRunHistoryStore.setState({ workflowRunId: item.id, runningStatus: item.status as WorkflowRunningStatus })} onClick={() => useRunHistoryStore.setState({
currentSequenceNumber: item.sequence_number,
workflowRunId: item.id,
runningStatus: item.status as WorkflowRunningStatus,
})}
> >
{ {
appDetail?.mode === 'workflow' && item.status === WorkflowRunningStatus.Failed && ( appDetail?.mode === 'workflow' && item.status === WorkflowRunningStatus.Failed && (
......
...@@ -21,7 +21,7 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => { ...@@ -21,7 +21,7 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => {
const getTime = (time: number) => { const getTime = (time: number) => {
if (time < 1) if (time < 1)
return `${time * 1000} ms` return `${(time * 1000).toFixed(3)} ms`
if (time > 60) if (time > 60)
return `${parseInt(Math.round(time / 60).toString())} m ${(time % 60).toFixed(3)} s` return `${parseInt(Math.round(time / 60).toString())} m ${(time % 60).toFixed(3)} s`
} }
...@@ -53,7 +53,7 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => { ...@@ -53,7 +53,7 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => {
/> />
<BlockIcon className='shrink-0 mr-2' type={nodeInfo.node_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='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.elapsed_time)} · ${getTokenCount(nodeInfo.execution_metadata.total_tokens)} tokens`}</div> <div className='shrink-0 text-gray-500 text-xs leading-[18px]'>{`${getTime(nodeInfo.elapsed_time)} · ${getTokenCount(nodeInfo.execution_metadata?.total_tokens || 0)} tokens`}</div>
{nodeInfo.status === 'succeeded' && ( {nodeInfo.status === 'succeeded' && (
<CheckCircle className='shrink-0 ml-2 w-3.5 h-3.5 text-[#12B76A]' /> <CheckCircle className='shrink-0 ml-2 w-3.5 h-3.5 text-[#12B76A]' />
)} )}
...@@ -73,34 +73,45 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => { ...@@ -73,34 +73,45 @@ const NodePanel: FC<Props> = ({ nodeInfo, collapsed, collapseHandle }) => {
{!collapsed && ( {!collapsed && (
<div className='pb-2'> <div className='pb-2'>
<div className='px-[10px] py-1'> <div className='px-[10px] py-1'>
{/* ###TODO### no data */}
{nodeInfo.status === 'stopped' && ( {nodeInfo.status === 'stopped' && (
<div className='px-3 py-[10px] bg-[#fffaeb] rounded-lg border-[0.5px] border-[rbga(0,0,0,0.05)] text-xs leading-[18px] text-[#dc6803] shadow-xs'>{t('workflow.tracing.stopBy', { user: 'Evan' })}</div> <div className='px-3 py-[10px] bg-[#fffaeb] rounded-lg border-[0.5px] border-[rbga(0,0,0,0.05)] text-xs leading-[18px] text-[#dc6803] shadow-xs'>{t('workflow.tracing.stopBy', { user: nodeInfo.created_by ? nodeInfo.created_by.name : 'N/A' })}</div>
)} )}
{nodeInfo.status === 'failed' && ( {nodeInfo.status === 'failed' && (
<div className='px-3 py-[10px] bg-[#fef3f2] rounded-lg border-[0.5px] border-[rbga(0,0,0,0.05)] text-xs leading-[18px] text-[#d92d20] shadow-xs'>{nodeInfo.error}</div> <div className='px-3 py-[10px] bg-[#fef3f2] rounded-lg border-[0.5px] border-[rbga(0,0,0,0.05)] text-xs leading-[18px] text-[#d92d20] shadow-xs'>{nodeInfo.error}</div>
)} )}
</div> </div>
<div className='px-[10px] py-1'> <div className='px-[10px] py-1'>
{/* ###TODO### value */}
<CodeEditor <CodeEditor
readOnly readOnly
title={<div>INPUT</div>} title={<div>INPUT</div>}
language={CodeLanguage.json} language={CodeLanguage.json}
value={''} value={JSON.stringify(nodeInfo.inputs)}
onChange={() => {}}
/>
</div>
<div className='px-[10px] py-1'>
{/* ###TODO### value */}
<CodeEditor
readOnly
title={<div>OUTPUT</div>}
language={CodeLanguage.json}
value={''}
onChange={() => {}} onChange={() => {}}
/> />
</div> </div>
{/* ###TODO### conditions by type */}
{nodeInfo.process_data && (
<div className='px-[10px] py-1'>
<CodeEditor
readOnly
title={<div>PROCESS DATA</div>}
language={CodeLanguage.json}
value={JSON.stringify(nodeInfo.process_data)}
onChange={() => {}}
/>
</div>
)}
{nodeInfo.outputs && (
<div className='px-[10px] py-1'>
<CodeEditor
readOnly
title={<div>OUTPUT</div>}
language={CodeLanguage.json}
value={JSON.stringify(nodeInfo.outputs)}
onChange={() => {}}
/>
</div>
)}
</div> </div>
)} )}
</div> </div>
......
...@@ -51,6 +51,7 @@ const ResultPanel: FC<ResultPanelProps> = ({ ...@@ -51,6 +51,7 @@ const ResultPanel: FC<ResultPanelProps> = ({
value={JSON.stringify(inputs)} value={JSON.stringify(inputs)}
onChange={() => {}} onChange={() => {}}
/> />
{/* ###TODO### */}
{process_data && ( {process_data && (
<CodeEditor <CodeEditor
readOnly readOnly
......
...@@ -28,7 +28,7 @@ const Tracing: FC<TracingProps> = ({ runID }) => { ...@@ -28,7 +28,7 @@ const Tracing: FC<TracingProps> = ({ runID }) => {
url: `/apps/${appID}/workflow-runs/${runID}/node-executions`, url: `/apps/${appID}/workflow-runs/${runID}/node-executions`,
}) })
const collapseState = nodeList.map(node => node.status === 'succeeded') const collapseState = nodeList.map(node => node.status === 'succeeded')
setList(nodeList) setList(nodeList.reverse())
setCollapseState(collapseState) setCollapseState(collapseState)
setLoading(false) setLoading(false)
} }
......
...@@ -14,6 +14,7 @@ import type { WorkflowRunningStatus } from './types' ...@@ -14,6 +14,7 @@ import type { WorkflowRunningStatus } from './types'
type State = { type State = {
mode: Mode mode: Mode
taskId: string taskId: string
currentSequenceNumber: number
workflowRunId: string workflowRunId: string
showRunHistory: boolean showRunHistory: boolean
showFeaturesPanel: boolean showFeaturesPanel: boolean
...@@ -32,6 +33,7 @@ type State = { ...@@ -32,6 +33,7 @@ type State = {
type Action = { type Action = {
setMode: (mode: Mode) => void setMode: (mode: Mode) => void
setTaskId: (taskId: string) => void setTaskId: (taskId: string) => void
setCurrentSequenceNumber: (currentSequenceNumber: number) => void
setWorkflowRunId: (workflowRunId: string) => void setWorkflowRunId: (workflowRunId: string) => void
setShowRunHistory: (showRunHistory: boolean) => void setShowRunHistory: (showRunHistory: boolean) => void
setShowFeaturesPanel: (showFeaturesPanel: boolean) => void setShowFeaturesPanel: (showFeaturesPanel: boolean) => void
...@@ -51,6 +53,8 @@ export const useStore = create<State & Action>(set => ({ ...@@ -51,6 +53,8 @@ export const useStore = create<State & Action>(set => ({
mode: Mode.Editing, mode: Mode.Editing,
taskId: '', taskId: '',
setTaskId: taskId => set(() => ({ taskId })), setTaskId: taskId => set(() => ({ taskId })),
currentSequenceNumber: 0,
setCurrentSequenceNumber: currentSequenceNumber => set(() => ({ currentSequenceNumber })),
workflowRunId: '', workflowRunId: '',
setWorkflowRunId: workflowRunId => set(() => ({ workflowRunId })), setWorkflowRunId: workflowRunId => set(() => ({ workflowRunId })),
setMode: mode => set(() => ({ mode })), setMode: mode => set(() => ({ mode })),
......
...@@ -50,6 +50,7 @@ export type NodeTracingListResponse = { ...@@ -50,6 +50,7 @@ export type NodeTracingListResponse = {
export type WorkflowStartedResponse = { export type WorkflowStartedResponse = {
task_id: string task_id: string
workflow_run_id: string workflow_run_id: string
sequence_number: number
event: string event: string
data: { data: {
id: string id: string
......
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