mirror of https://github.com/langgenius/dify.git
refact workflow run log
This commit is contained in:
parent
1429b30e84
commit
7e94056507
|
|
@ -0,0 +1,43 @@
|
|||
import {
|
||||
RiAlertFill,
|
||||
RiCheckboxCircleFill,
|
||||
RiErrorWarningLine,
|
||||
RiLoader2Line,
|
||||
} from '@remixicon/react'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type NodeStatusIconProps = {
|
||||
status: string
|
||||
className?: string
|
||||
}
|
||||
const NodeStatusIcon = ({
|
||||
status,
|
||||
className,
|
||||
}: NodeStatusIconProps) => {
|
||||
return (
|
||||
<>
|
||||
{
|
||||
status === 'succeeded' && (
|
||||
<RiCheckboxCircleFill className={cn('shrink-0 w-4 h-4 text-text-success', className)} />
|
||||
)
|
||||
}
|
||||
{
|
||||
status === 'failed' && (
|
||||
<RiErrorWarningLine className={cn('shrink-0 w-4 h-4 text-text-warning', className)} />
|
||||
)
|
||||
}
|
||||
{
|
||||
(status === 'stopped' || status === 'exception') && (
|
||||
<RiAlertFill className={cn('shrink-0 w-4 h-4 text-text-warning-secondary', className)} />
|
||||
)
|
||||
}
|
||||
{
|
||||
status === 'running' && (
|
||||
<RiLoader2Line className={cn('shrink-0 w-4 h-4 text-text-accent animate-spin', className)} />
|
||||
)
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default NodeStatusIcon
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import { useState } from 'react'
|
||||
import {
|
||||
RiArrowRightSLine,
|
||||
RiListView,
|
||||
} from '@remixicon/react'
|
||||
import cn from '@/utils/classnames'
|
||||
import Button from '@/app/components/base/button'
|
||||
import type { AgentLogItemWithChildren } from '@/types/workflow'
|
||||
import NodeStatusIcon from '@/app/components/workflow/nodes/_base/components/node-status-icon'
|
||||
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
|
||||
type AgentLogItemProps = {
|
||||
item: AgentLogItemWithChildren
|
||||
}
|
||||
const AgentLogItem = ({
|
||||
item,
|
||||
}: AgentLogItemProps) => {
|
||||
const {
|
||||
label,
|
||||
status,
|
||||
children,
|
||||
data,
|
||||
} = item
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
|
||||
return (
|
||||
<div className='border-[0.5px] border-components-panel-border rounded-[10px]'>
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center pl-1.5 pt-2 pr-3 pb-2',
|
||||
expanded && 'pb-1',
|
||||
)}
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
>
|
||||
{
|
||||
expanded
|
||||
? <RiArrowRightSLine className='shrink-0 w-4 h-4 rotate-90' />
|
||||
: <RiArrowRightSLine className='shrink-0 w-4 h-4' />
|
||||
}
|
||||
<div className='shrink-0 mr-1.5 w-5 h-5'></div>
|
||||
<div className='grow system-sm-semibold-uppercase text-text-secondary truncate'>{label}</div>
|
||||
<div className='shrink-0 mr-2 system-xs-regular text-text-tertiary'>0.02s</div>
|
||||
<NodeStatusIcon status={status} />
|
||||
</div>
|
||||
{
|
||||
expanded && (
|
||||
<div className='p-1 pt-0'>
|
||||
{
|
||||
!!children.length && (
|
||||
<Button
|
||||
className='flex items-center justify-between mb-1 w-full'
|
||||
variant='tertiary'
|
||||
onClick={() => {}}
|
||||
>
|
||||
<div className='flex items-center'>
|
||||
<RiListView className='mr-1 w-4 h-4 text-components-button-tertiary-text shrink-0' />
|
||||
{`${children.length} Action Logs`}
|
||||
</div>
|
||||
<div className='flex'>
|
||||
<RiArrowRightSLine className='w-4 h-4 text-components-button-tertiary-text shrink-0' />
|
||||
</div>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
{
|
||||
data && (
|
||||
<CodeEditor
|
||||
readOnly
|
||||
title={<div>{'data'.toLocaleUpperCase()}</div>}
|
||||
language={CodeLanguage.json}
|
||||
value={data}
|
||||
isJSONStringifyBeauty
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AgentLogItem
|
||||
|
|
@ -1,11 +1,19 @@
|
|||
import { RiArrowRightLine } from '@remixicon/react'
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
NodeTracing,
|
||||
} from '@/types/workflow'
|
||||
|
||||
type AgentLogTriggerProps = {
|
||||
onDetail?: () => void
|
||||
nodeInfo: NodeTracing
|
||||
onShowAgentResultList: (agentLogs: AgentLogItemWithChildren[]) => void
|
||||
}
|
||||
const AgentLogTrigger = ({
|
||||
onDetail,
|
||||
nodeInfo,
|
||||
onShowAgentResultList,
|
||||
}: AgentLogTriggerProps) => {
|
||||
const { agentLog } = nodeInfo
|
||||
|
||||
return (
|
||||
<div className='bg-components-button-tertiary-bg rounded-[10px]'>
|
||||
<div className='flex items-center px-3 pt-2 system-2xs-medium-uppercase text-text-tertiary'>
|
||||
|
|
@ -16,7 +24,7 @@ const AgentLogTrigger = ({
|
|||
<div className='grow mx-0.5 px-1 system-xs-medium text-text-secondary'></div>
|
||||
<div
|
||||
className='shrink-0 flex items-center px-[1px] system-xs-regular-uppercase text-text-tertiary cursor-pointer'
|
||||
onClick={onDetail}
|
||||
onClick={() => onShowAgentResultList(agentLog || [])}
|
||||
>
|
||||
Detail
|
||||
<RiArrowRightLine className='ml-0.5 w-3.5 h-3.5' />
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import Button from '@/app/components/base/button'
|
||||
import { RiArrowLeftLine } from '@remixicon/react'
|
||||
import TracingPanel from '../tracing-panel'
|
||||
import AgentLogItem from './agent-log-item'
|
||||
import type { AgentLogItemWithChildren } from '@/types/workflow'
|
||||
|
||||
type AgentResultPanelProps = {
|
||||
onBack: () => void
|
||||
list: AgentLogItemWithChildren[]
|
||||
setAgentResultList: (list: AgentLogItemWithChildren[]) => void
|
||||
}
|
||||
const AgentResultPanel = ({
|
||||
onBack,
|
||||
list,
|
||||
}: AgentResultPanelProps) => {
|
||||
return (
|
||||
<div className='overflow-y-auto'>
|
||||
|
|
@ -15,7 +17,7 @@ const AgentResultPanel = ({
|
|||
className='shrink-0 px-[5px]'
|
||||
size='small'
|
||||
variant='ghost-accent'
|
||||
onClick={onBack}
|
||||
onClick={() => {}}
|
||||
>
|
||||
<RiArrowLeftLine className='mr-1 w-3.5 h-3.5' />
|
||||
Back
|
||||
|
|
@ -28,14 +30,23 @@ const AgentResultPanel = ({
|
|||
className='px-[5px]'
|
||||
size='small'
|
||||
variant='ghost-accent'
|
||||
onClick={onBack}
|
||||
onClick={() => {}}
|
||||
>
|
||||
close
|
||||
</Button>
|
||||
</div>
|
||||
<TracingPanel
|
||||
list={[]}
|
||||
/>
|
||||
{
|
||||
<div className='p-2'>
|
||||
{
|
||||
list.map(item => (
|
||||
<AgentLogItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,2 @@
|
|||
export { default as AgentLogTrigger } from './agent-log-trigger'
|
||||
export { default as AgentResultPanel } from './agent-result-panel'
|
||||
export { default as AgentToolCallResultPanel } from './tool-call-result-panel'
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
import Button from '@/app/components/base/button'
|
||||
import { RiArrowLeftLine } from '@remixicon/react'
|
||||
import TracingPanel from '../tracing-panel'
|
||||
|
||||
type ToolCallResultPanelProps = {
|
||||
onBack: () => void
|
||||
onClose: () => void
|
||||
}
|
||||
const ToolCallResultPanel = ({
|
||||
onBack,
|
||||
onClose,
|
||||
}: ToolCallResultPanelProps) => {
|
||||
return (
|
||||
<div className='overflow-y-auto'>
|
||||
<div className='flex items-center p-1 pr-3 h-8'>
|
||||
<Button
|
||||
className='shrink-0 px-[5px]'
|
||||
size='small'
|
||||
variant='ghost-accent'
|
||||
onClick={onBack}
|
||||
>
|
||||
<RiArrowLeftLine className='mr-1 w-3.5 h-3.5' />
|
||||
Back
|
||||
</Button>
|
||||
<div className='shrink-0 mx-0.5 system-xs-regular text-divider-deep'>/</div>
|
||||
<div className='grow px-[5px] system-xs-medium-uppercase'>
|
||||
10 Logs
|
||||
</div>
|
||||
<Button
|
||||
className='px-[5px]'
|
||||
size='small'
|
||||
variant='ghost-accent'
|
||||
onClick={onClose}
|
||||
>
|
||||
close
|
||||
</Button>
|
||||
</div>
|
||||
<TracingPanel
|
||||
list={[]}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ToolCallResultPanel
|
||||
|
|
@ -3,7 +3,11 @@ import {
|
|||
useState,
|
||||
} from 'react'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import type { IterationDurationMap, NodeTracing } from '@/types/workflow'
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
IterationDurationMap,
|
||||
NodeTracing,
|
||||
} from '@/types/workflow'
|
||||
|
||||
export const useLogs = () => {
|
||||
const [showRetryDetail, {
|
||||
|
|
@ -28,13 +32,10 @@ export const useLogs = () => {
|
|||
setIterationResultDurationMap(iterDurationMap)
|
||||
}, [setShowIteratingDetailTrue, setIterationResultList, setIterationResultDurationMap])
|
||||
|
||||
const [showAgentDetail, {
|
||||
setTrue: setShowAgentDetailTrue,
|
||||
setFalse: setShowAgentDetailFalse,
|
||||
}] = useBoolean(false)
|
||||
const [agentResultList, setAgentResultList] = useState<AgentLogItemWithChildren[]>([])
|
||||
|
||||
return {
|
||||
showSpecialResultPanel: showRetryDetail || showIteratingDetail,
|
||||
showSpecialResultPanel: showRetryDetail || showIteratingDetail || !!agentResultList.length,
|
||||
showRetryDetail,
|
||||
setShowRetryDetailTrue,
|
||||
setShowRetryDetailFalse,
|
||||
|
|
@ -51,8 +52,7 @@ export const useLogs = () => {
|
|||
setIterationResultDurationMap,
|
||||
handleShowIterationResultList,
|
||||
|
||||
showAgentDetail,
|
||||
setShowAgentDetailTrue,
|
||||
setShowAgentDetailFalse,
|
||||
agentResultList,
|
||||
setAgentResultList,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,11 @@ import cn from '@/utils/classnames'
|
|||
import StatusContainer from '@/app/components/workflow/run/status-container'
|
||||
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
|
||||
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
|
||||
import type { IterationDurationMap, NodeTracing } from '@/types/workflow'
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
IterationDurationMap,
|
||||
NodeTracing,
|
||||
} from '@/types/workflow'
|
||||
import ErrorHandleTip from '@/app/components/workflow/nodes/_base/components/error-handle/error-handle-tip'
|
||||
import { hasRetryNode } from '@/app/components/workflow/utils'
|
||||
|
||||
|
|
@ -30,6 +34,7 @@ type Props = {
|
|||
hideProcessDetail?: boolean
|
||||
onShowIterationDetail?: (detail: NodeTracing[][], iterDurationMap: IterationDurationMap) => void
|
||||
onShowRetryDetail?: (detail: NodeTracing[]) => void
|
||||
onShowAgentResultList?: (detail: AgentLogItemWithChildren[]) => void
|
||||
notShowIterationNav?: boolean
|
||||
justShowIterationNavArrow?: boolean
|
||||
justShowRetryNavArrow?: boolean
|
||||
|
|
@ -43,6 +48,7 @@ const NodePanel: FC<Props> = ({
|
|||
hideProcessDetail,
|
||||
onShowIterationDetail,
|
||||
onShowRetryDetail,
|
||||
onShowAgentResultList,
|
||||
notShowIterationNav,
|
||||
justShowIterationNavArrow,
|
||||
}) => {
|
||||
|
|
@ -142,8 +148,11 @@ const NodePanel: FC<Props> = ({
|
|||
/>
|
||||
)}
|
||||
{
|
||||
isAgentNode && (
|
||||
<AgentLogTrigger />
|
||||
isAgentNode && onShowAgentResultList && (
|
||||
<AgentLogTrigger
|
||||
nodeInfo={nodeInfo}
|
||||
onShowAgentResultList={onShowAgentResultList}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div className={cn('mb-1', hideInfo && '!px-2 !py-0.5')}>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
import { RetryResultPanel } from './retry-log'
|
||||
import { IterationResultPanel } from './iteration-log'
|
||||
import { AgentResultPanel } from './agent-log'
|
||||
import type { IterationDurationMap, NodeTracing } from '@/types/workflow'
|
||||
import type {
|
||||
AgentLogItemWithChildren,
|
||||
IterationDurationMap,
|
||||
NodeTracing,
|
||||
} from '@/types/workflow'
|
||||
|
||||
type SpecialResultPanelProps = {
|
||||
showRetryDetail: boolean
|
||||
|
|
@ -13,8 +17,8 @@ type SpecialResultPanelProps = {
|
|||
iterationResultList: NodeTracing[][]
|
||||
iterationResultDurationMap: IterationDurationMap
|
||||
|
||||
showAgentDetail: boolean
|
||||
setShowAgentDetailFalse: () => void
|
||||
agentResultList: AgentLogItemWithChildren[]
|
||||
setAgentResultList: (list: AgentLogItemWithChildren[]) => void
|
||||
}
|
||||
const SpecialResultPanel = ({
|
||||
showRetryDetail,
|
||||
|
|
@ -26,8 +30,8 @@ const SpecialResultPanel = ({
|
|||
iterationResultList,
|
||||
iterationResultDurationMap,
|
||||
|
||||
showAgentDetail,
|
||||
setShowAgentDetailFalse,
|
||||
agentResultList,
|
||||
setAgentResultList,
|
||||
}: SpecialResultPanelProps) => {
|
||||
return (
|
||||
<>
|
||||
|
|
@ -49,9 +53,10 @@ const SpecialResultPanel = ({
|
|||
)
|
||||
}
|
||||
{
|
||||
showAgentDetail && (
|
||||
!!agentResultList.length && (
|
||||
<AgentResultPanel
|
||||
onBack={setShowAgentDetailFalse}
|
||||
list={agentResultList}
|
||||
setAgentResultList={setAgentResultList}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,8 +215,8 @@ const TracingPanel: FC<TracingPanelProps> = ({
|
|||
iterationResultDurationMap,
|
||||
handleShowIterationResultList,
|
||||
|
||||
showAgentDetail,
|
||||
setShowAgentDetailFalse,
|
||||
agentResultList,
|
||||
setAgentResultList,
|
||||
} = useLogs()
|
||||
|
||||
const renderNode = (node: TracingNodeProps) => {
|
||||
|
|
@ -270,6 +270,7 @@ const TracingPanel: FC<TracingPanelProps> = ({
|
|||
nodeInfo={node.data!}
|
||||
onShowIterationDetail={handleShowIterationResultList}
|
||||
onShowRetryDetail={handleShowRetryResultList}
|
||||
onShowAgentResultList={setAgentResultList}
|
||||
justShowIterationNavArrow={true}
|
||||
justShowRetryNavArrow={true}
|
||||
hideInfo={hideNodeInfo}
|
||||
|
|
@ -292,8 +293,8 @@ const TracingPanel: FC<TracingPanelProps> = ({
|
|||
iterationResultList={iterationResultList}
|
||||
iterationResultDurationMap={iterationResultDurationMap}
|
||||
|
||||
showAgentDetail={showAgentDetail}
|
||||
setShowAgentDetailFalse={setShowAgentDetailFalse}
|
||||
agentResultList={agentResultList}
|
||||
setAgentResultList={setAgentResultList}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue