Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/workflow retry #11885

Merged
merged 14 commits into from
Dec 20, 2024
Prev Previous commit
Next Next commit
fix: retry on node
  • Loading branch information
zxhlyh committed Dec 20, 2024
commit 71b0b1984618ffb80b8bc7be7048c8555a15d87d
12 changes: 12 additions & 0 deletions web/app/components/workflow/hooks/use-workflow-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,12 @@ export const useWorkflowRun = () => {
workflowRunningData,
setWorkflowRunningData,
} = workflowStore.getState()
const {
getNodes,
setNodes,
} = store.getState()

const nodes = getNodes()
setWorkflowRunningData(produce(workflowRunningData!, (draft) => {
const tracing = draft.tracing!
const currentRetryNodeIndex = tracing.findIndex(trace => trace.node_id === data.node_id)
Expand All @@ -640,6 +646,12 @@ export const useWorkflowRun = () => {
draft.tracing![currentRetryNodeIndex].retryDetail = [data as NodeTracing]
}
}))
const newNodes = produce(nodes, (draft) => {
const currentNode = draft.find(node => node.id === data.node_id)!

currentNode.data._retryIndex = data.retry_index
})
setNodes(newNodes)

if (onNodeRetry)
onNodeRetry(params)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,85 @@
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiAlertFill,
RiCheckboxCircleFill,
RiLoader2Line,
} from '@remixicon/react'
import type { Node } from '@/app/components/workflow/types'
import { NodeRunningStatus } from '@/app/components/workflow/types'
import cn from '@/utils/classnames'

type RetryOnNodeProps = Pick<Node, 'id' | 'data'>
const RetryOnNode = ({
data,
}: RetryOnNodeProps) => {
const { t } = useTranslation()
const { retry_config } = data
const showSelectedBorder = data.selected || data._isBundled || data._isEntering
const {
isRunning,
isSuccessful,
isException,
isFailed,
} = useMemo(() => {
return {
isRunning: data._runningStatus === NodeRunningStatus.Running && !showSelectedBorder,
isSuccessful: data._runningStatus === NodeRunningStatus.Succeeded && !showSelectedBorder,
isFailed: data._runningStatus === NodeRunningStatus.Failed && !showSelectedBorder,
isException: data._runningStatus === NodeRunningStatus.Exception && !showSelectedBorder,
}
}, [data._runningStatus, showSelectedBorder])
const showDefault = !isRunning && !isSuccessful && !isException && !isFailed

if (!retry_config)
return null

return (
<div className='px-3'>
<div className='flex items-center px-[5px] py-1 bg-workflow-block-parma-bg rounded-md system-xs-medium-uppercase text-text-tertiary'>
{t('workflow.nodes.common.retry.retryTimes', { times: retry_config.max_retries })}
<div className={cn(
'flex items-center justify-between px-[5px] py-1 bg-workflow-block-parma-bg border-[0.5px] border-transparent rounded-md system-xs-medium-uppercase text-text-tertiary',
isRunning && 'bg-state-accent-hover border-state-accent-active text-text-accent',
isSuccessful && 'bg-state-success-hover border-state-success-active text-text-success',
(isException || isFailed) && 'bg-state-warning-hover border-state-warning-active text-text-warning',
)}>
<div className='flex items-center'>
{
showDefault && (
t('workflow.nodes.common.retry.retryTimes', { times: retry_config.max_retries })
)
}
{
isRunning && (
<>
<RiLoader2Line className='animate-spin mr-1 w-3.5 h-3.5' />
{t('workflow.nodes.common.retry.retrying')}
</>
)
}
{
isSuccessful && (
<>
<RiCheckboxCircleFill className='mr-1 w-3.5 h-3.5' />
{t('workflow.nodes.common.retry.retrySuccessful')}
</>
)
}
{
(isFailed || isException) && (
<>
<RiAlertFill className='mr-1 w-3.5 h-3.5' />
{t('workflow.nodes.common.retry.retryFailed')}
</>
)
}
</div>
{
!showDefault && (
<div>
{data._retryIndex}/{data.retry_config?.max_retries}
</div>
)
}
</div>
</div>
)
Expand Down
4 changes: 4 additions & 0 deletions web/app/components/workflow/nodes/tool/panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/befo
import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars'
import ResultPanel from '@/app/components/workflow/run/result-panel'
import { useRetryDetailShowInSingleRun } from '@/app/components/workflow/nodes/_base/components/retry/hooks'
import { useToolIcon } from '@/app/components/workflow/hooks'

const i18nPrefix = 'workflow.nodes.tool'

Expand Down Expand Up @@ -49,6 +50,7 @@ const Panel: FC<NodePanelProps<ToolNodeType>> = ({
handleStop,
runResult,
} = useConfig(id, data)
const toolIcon = useToolIcon(data)
const {
retryDetails,
handleRetryDetailsChange,
Expand Down Expand Up @@ -148,6 +150,8 @@ const Panel: FC<NodePanelProps<ToolNodeType>> = ({
{isShowSingleRun && (
<BeforeRunForm
nodeName={inputs.title}
nodeType={inputs.type}
toolIcon={toolIcon}
onHide={hideSingleRun}
forms={singleRunForms}
runningStatus={runningStatus}
Expand Down
1 change: 1 addition & 0 deletions web/app/components/workflow/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export type CommonNodeType<T = {}> = {
_iterationIndex?: number
_inParallelHovering?: boolean
_waitingRun?: boolean
_retryIndex?: number
isInIteration?: boolean
iteration_id?: string
selected?: boolean
Expand Down
2 changes: 1 addition & 1 deletion web/i18n/en-US/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ const translation = {
maxRetries: 'max retries',
retryInterval: 'retry interval',
retryTimes: 'Retry {{times}} times on failure',
retrying: 'Retrying',
retrying: 'Retrying...',
retrySuccessful: 'Retry successful',
retryFailed: 'Retry failed',
retryFailedTimes: '{{times}} retries failed',
Expand Down
2 changes: 1 addition & 1 deletion web/i18n/zh-Hans/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ const translation = {
maxRetries: '最大重试次数',
retryInterval: '重试间隔',
retryTimes: '失败时重试 {{times}} 次',
retrying: '重试中',
retrying: '重试中...',
retrySuccessful: '重试成功',
retryFailed: '重试失败',
retryFailedTimes: '{{times}} 次重试失败',
Expand Down
1 change: 1 addition & 0 deletions web/types/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export type NodeFinishedResponse = {
}
created_at: number
files?: FileResponse[]
retry_index?: number
}
}

Expand Down
Loading