Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion apps/application/workflow/i_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@desc:
"""
import time
from enum import Enum
from typing import Optional, Type, Callable

from rest_framework import serializers
Expand All @@ -17,6 +18,12 @@
from common.utils.logger import maxkb_logger


class Signal(str, Enum):
BREAK = 'BREAK'
CONTINUE = 'CONTINUE'
FORM = 'FORM'


class INode:
# 当前节点支持的工作流类型
supported_workflow_type_list = []
Expand Down Expand Up @@ -92,13 +99,14 @@ def _run(self):
self.execute()
self.complete(Status.SUCCESS)

def complete(self, status, anchors=None, error=None):
def complete(self, status, anchors=None, error=None, signal: Optional[Signal] = None):
"""
节点结束调用函数

@param status: 状态
@param anchors 锚点信息
@param error: 错误信息
@param signal: 信号
@return:
"""
if self._completed:
Expand All @@ -108,6 +116,9 @@ def complete(self, status, anchors=None, error=None):
if error:
self.data['error'] = str(error)
self.data['run_time'] = time.time() - self.data['start_time']
if signal:
self.workflow_manage.signal = signal
anchors = []
if anchors is None:
anchors = [self.success_anchor() if status == Status.SUCCESS else self.fail_anchor()]
self._dispatch(anchors)
Expand Down
9 changes: 9 additions & 0 deletions apps/application/workflow/nodes/loop_break_node/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎虎虎
@file: __init__.py
@date:2026/7/6 15:00
@desc:
"""
from .loop_break_node import LoopBreakNode
45 changes: 45 additions & 0 deletions apps/application/workflow/nodes/loop_break_node/loop_break_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎虎虎
@file: loop_break_node.py
@date:2026/7/6 15:00
@desc:
"""
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers

from application.workflow.compare import do_assertion
from application.workflow.common import WorkflowType
from application.workflow.i_node import INode, Signal
from application.workflow.status import Status


class ConditionSerializer(serializers.Serializer):
compare = serializers.CharField(required=True, label=_("Comparator"))
value = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_("value"))
field = serializers.ListField(required=True, label=_("Fields"))


class LoopBreakNodeSerializer(serializers.Serializer):
condition = serializers.CharField(required=True, label=_("Condition or|and"))
condition_list = ConditionSerializer(many=True)


class LoopBreakNode(INode):
serializer_class = LoopBreakNodeSerializer
supported_workflow_type_list = [WorkflowType.APPLICATION, WorkflowType.KNOWLEDGE, WorkflowType.TOOL]
type = 'loop-break-node'

def execute(self):
node_params = self.get_parameters()
condition = node_params.get('condition')
condition_list = node_params.get('condition_list', [])

is_break = do_assertion(self.workflow_manage, condition, condition_list)
self.write_context('is_break', is_break)

if is_break:
self.complete(Status.SUCCESS, signal=Signal.BREAK)
return
self.complete(Status.SUCCESS)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎虎虎
@file: __init__.py
@date:2026/7/6 15:10
@desc:
"""
from .loop_continue_node import LoopContinueNode
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎虎虎
@file: loop_continue_node.py
@date:2026/7/6 15:10
@desc:
"""
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers

from application.workflow.compare import do_assertion
from application.workflow.common import WorkflowType
from application.workflow.i_node import INode, Signal
from application.workflow.status import Status


class ConditionSerializer(serializers.Serializer):
compare = serializers.CharField(required=True, label=_("Comparator"))
value = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_("value"))
field = serializers.ListField(required=True, label=_("Fields"))


class LoopContinueNodeSerializer(serializers.Serializer):
condition = serializers.CharField(required=True, label=_("Condition or|and"))
condition_list = ConditionSerializer(many=True)


class LoopContinueNode(INode):
serializer_class = LoopContinueNodeSerializer
supported_workflow_type_list = [WorkflowType.APPLICATION, WorkflowType.KNOWLEDGE, WorkflowType.TOOL]
type = 'loop-continue-node'

def execute(self):
node_params = self.get_parameters()
condition = node_params.get('condition')
condition_list = node_params.get('condition_list', [])

is_continue = do_assertion(self.workflow_manage, condition, condition_list)
self.write_context('is_continue', is_continue)

if is_continue:
self.complete(Status.SUCCESS, signal=Signal.CONTINUE)
return
self.complete(Status.SUCCESS)
12 changes: 11 additions & 1 deletion apps/application/workflow/nodes/loop_node/loop_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from rest_framework import serializers

from application.workflow.common import WorkflowType, new_instance
from application.workflow.i_node import INode
from application.workflow.i_node import INode, Signal

from application.workflow.message.struct.content import NodeInfo
from application.workflow.message.struct.text_content import TextContent
Expand Down Expand Up @@ -121,6 +121,16 @@ def on_complete(wf_manage, error):
self.write_context('index', index)
self.write_context('item', item)

if wf_manage.signal == Signal.BREAK:
self.write_context('answer', self._answer_text)
self.write_context('run_time', time.time() - self.data.get('start_time', time.time()))
self.complete(Status.SUCCESS)
return

if wf_manage.signal == Signal.CONTINUE:
self._run_next()
return

if error:
self.write_context('error_message', str(error))
return
Expand Down
1 change: 1 addition & 0 deletions apps/application/workflow/workflow_manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def __init__(self,
self.parameters = parameters
self.context = {}
self.nodes = []
self.signal = None
self.start_node = get_start_node(workflow, self)

def run(self):
Expand Down
Loading