mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-28 23:32:48 +00:00
feat: knowledge workflow
This commit is contained in:
parent
7eddb4bd83
commit
bc1a4809e0
|
|
@ -6,7 +6,7 @@
|
|||
@date:2024/12/11 17:57
|
||||
@desc:
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
from typing import List, Dict
|
||||
|
||||
from django.db.models import QuerySet
|
||||
|
|
@ -90,6 +90,16 @@ class EdgeNode:
|
|||
self.node = node
|
||||
|
||||
|
||||
class WorkflowMode(Enum):
|
||||
APPLICATION = "application"
|
||||
|
||||
APPLICATION_LOOP = "application-loop"
|
||||
|
||||
KNOWLEDGE = "knowledge"
|
||||
|
||||
KNOWLEDGE_LOOP = "knowledge-loop"
|
||||
|
||||
|
||||
class Workflow:
|
||||
"""
|
||||
节点列表
|
||||
|
|
@ -112,7 +122,10 @@ class Workflow:
|
|||
"""
|
||||
next_node_map: Dict[str, List[EdgeNode]]
|
||||
|
||||
def __init__(self, nodes: List[Node], edges: List[Edge]):
|
||||
workflow_mode: WorkflowMode
|
||||
|
||||
def __init__(self, nodes: List[Node], edges: List[Edge],
|
||||
workflow_mode: WorkflowMode = WorkflowMode.APPLICATION.value):
|
||||
self.nodes = nodes
|
||||
self.edges = edges
|
||||
self.node_map = {node.id: node for node in nodes}
|
||||
|
|
@ -125,6 +138,7 @@ class Workflow:
|
|||
self.next_node_map = {key: [EdgeNode(edge, self.node_map.get(edge.targetNodeId)) for edge in edges] for
|
||||
key, edges in
|
||||
group_by(edges, key=lambda edge: edge.sourceNodeId).items()}
|
||||
self.workflow_mode = workflow_mode
|
||||
|
||||
def get_node(self, node_id):
|
||||
"""
|
||||
|
|
@ -167,13 +181,13 @@ class Workflow:
|
|||
return [en.node for en in self.next_node_map.get(node_id, [])]
|
||||
|
||||
@staticmethod
|
||||
def new_instance(flow_obj: Dict):
|
||||
def new_instance(flow_obj: Dict, workflow_mode: WorkflowMode = WorkflowMode.APPLICATION.value):
|
||||
nodes = flow_obj.get('nodes')
|
||||
edges = flow_obj.get('edges')
|
||||
nodes = [Node(node.get('id'), node.get('type'), **node)
|
||||
for node in nodes]
|
||||
edges = [Edge(edge.get('id'), edge.get('type'), **edge) for edge in edges]
|
||||
return Workflow(nodes, edges)
|
||||
return Workflow(nodes, edges, workflow_mode)
|
||||
|
||||
def get_start_node(self):
|
||||
return self.get_node('start-node')
|
||||
|
|
@ -190,10 +204,9 @@ class Workflow:
|
|||
self.is_valid_base_node()
|
||||
self.is_valid_work_flow()
|
||||
|
||||
@staticmethod
|
||||
def is_valid_node_params(node: Node):
|
||||
def is_valid_node_params(self, node: Node):
|
||||
from application.flow.step_node import get_node
|
||||
get_node(node.type)(node, None, None)
|
||||
get_node(node.type, self.workflow_mode)(node, None, None)
|
||||
|
||||
def is_valid_node(self, node: Node):
|
||||
self.is_valid_node_params(node)
|
||||
|
|
|
|||
|
|
@ -96,6 +96,14 @@ class WorkFlowPostHandler:
|
|||
application_public_access_client.save()
|
||||
|
||||
|
||||
class KnowledgeWorkflowPostHandler(WorkFlowPostHandler):
|
||||
def __init__(self, chat_info):
|
||||
super().__init__(chat_info)
|
||||
|
||||
def handler(self, workflow):
|
||||
pass
|
||||
|
||||
|
||||
class NodeResult:
|
||||
def __init__(self, node_variable: Dict, workflow_variable: Dict,
|
||||
_write_context=write_context, _is_interrupt=is_interrupt):
|
||||
|
|
@ -152,6 +160,12 @@ class FlowParamsSerializer(serializers.Serializer):
|
|||
debug = serializers.BooleanField(required=True, label="是否debug")
|
||||
|
||||
|
||||
class KnowledgeFlowParamsSerializer(serializers.Serializer):
|
||||
knowledge_id = serializers.CharField(required=True, label="知识库id")
|
||||
data_source = serializers.DictField(required=True, label="数据源")
|
||||
knowledge_base = serializers.DictField(required=False, label="知识库设置")
|
||||
|
||||
|
||||
class INode:
|
||||
view_type = 'many_view'
|
||||
|
||||
|
|
@ -221,7 +235,7 @@ class INode:
|
|||
pass
|
||||
|
||||
def get_flow_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return FlowParamsSerializer
|
||||
return self.workflow_manage.get_params_serializer_class()
|
||||
|
||||
def get_write_error_context(self, e):
|
||||
self.status = 500
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
@project: MaxKB
|
||||
@Author:虎虎
|
||||
@file: Knowledge_workflow_manage.py
|
||||
@date:2025/11/13 19:02
|
||||
@desc:
|
||||
"""
|
||||
|
||||
from application.flow.common import Workflow
|
||||
from application.flow.i_step_node import WorkFlowPostHandler, KnowledgeFlowParamsSerializer
|
||||
from application.flow.workflow_manage import WorkflowManage
|
||||
from common.handle.base_to_response import BaseToResponse
|
||||
from common.handle.impl.response.system_to_response import SystemToResponse
|
||||
|
||||
|
||||
class KnowledgeWorkflowManage(WorkflowManage):
|
||||
|
||||
def __init__(self, flow: Workflow,
|
||||
params,
|
||||
work_flow_post_handler: WorkFlowPostHandler,
|
||||
base_to_response: BaseToResponse = SystemToResponse(),
|
||||
start_node_id=None,
|
||||
start_node_data=None, chat_record=None, child_node=None):
|
||||
super().__init__(flow, params, work_flow_post_handler, base_to_response, None, None, None,
|
||||
None,
|
||||
None, None, start_node_id, start_node_data, chat_record, child_node)
|
||||
|
||||
def get_params_serializer_class(self):
|
||||
return KnowledgeFlowParamsSerializer
|
||||
|
||||
def get_start_node(self):
|
||||
start_node_list = [node for node in self.flow.nodes if
|
||||
self.params.get('data_source', {}).get('node_id') == node.id]
|
||||
return start_node_list[0]
|
||||
|
|
@ -105,10 +105,10 @@ class LoopWorkflowManage(WorkflowManage):
|
|||
get_node_params=lambda node: node.properties.get('node_data')):
|
||||
for node in self.flow.nodes:
|
||||
if node.id == node_id:
|
||||
node_instance = get_node(node.type)(node,
|
||||
self.params, self, up_node_id_list,
|
||||
get_node_params,
|
||||
salt=self.get_index())
|
||||
node_instance = get_node(node.type, self.flow.workflow_mode)(node,
|
||||
self.params, self, up_node_id_list,
|
||||
get_node_params,
|
||||
salt=self.get_index())
|
||||
return node_instance
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -50,11 +50,14 @@ node_list = [BaseStartStepNode, BaseChatNode, BaseSearchKnowledgeNode, BaseSearc
|
|||
BaseIntentNode, BaseLoopNode, BaseLoopStartStepNode,
|
||||
BaseLoopContinueNode,
|
||||
BaseLoopBreakNode, BaseVariableSplittingNode, BaseParameterExtractionNode, BaseVariableAggregationNode,
|
||||
<<<<<<< Updated upstream
|
||||
BaseDataSourceLocalNode,BaseDataSourceWebNode,BaseKnowledgeWriteNode]
|
||||
=======
|
||||
BaseDataSourceLocalNode, BaseDataSourceWebNode]
|
||||
|
||||
node_map = {n.type: {w: n for w in n.support} for n in node_list}
|
||||
>>>>>>> Stashed changes
|
||||
|
||||
|
||||
def get_node(node_type):
|
||||
find_list = [node for node in node_list if node.type == node_type]
|
||||
if len(find_list) > 0:
|
||||
return find_list[0]
|
||||
return None
|
||||
def get_node(node_type, workflow_model):
|
||||
return node_map.get(node_type).get(workflow_model)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -34,7 +35,8 @@ class ChatNodeSerializer(serializers.Serializer):
|
|||
mcp_enable = serializers.BooleanField(required=False, label=_("Whether to enable MCP"))
|
||||
mcp_servers = serializers.JSONField(required=False, label=_("MCP Server"))
|
||||
mcp_tool_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("MCP Tool ID"))
|
||||
mcp_tool_ids = serializers.ListField(child=serializers.UUIDField(), required=False, allow_empty=True, label=_("MCP Tool IDs"), )
|
||||
mcp_tool_ids = serializers.ListField(child=serializers.UUIDField(), required=False, allow_empty=True,
|
||||
label=_("MCP Tool IDs"), )
|
||||
mcp_source = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("MCP Source"))
|
||||
|
||||
tool_enable = serializers.BooleanField(required=False, default=False, label=_("Whether to enable tools"))
|
||||
|
|
@ -42,14 +44,22 @@ class ChatNodeSerializer(serializers.Serializer):
|
|||
label=_("Tool IDs"), )
|
||||
mcp_output_enable = serializers.BooleanField(required=False, default=True, label=_("Whether to enable MCP output"))
|
||||
|
||||
|
||||
class IChatNode(INode):
|
||||
type = 'ai-chat-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP, WorkflowMode.KNOWLEDGE_LOOP,
|
||||
WorkflowMode.KNOWLEDGE]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return ChatNodeSerializer
|
||||
|
||||
def _run(self):
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
if [WorkflowMode.KNOWLEDGE, WorkflowMode.APPLICATION_LOOP].__contains__(
|
||||
self.workflow_manage.flow.workflow_mode):
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data,
|
||||
**{'history_chat_record': [], 'stream': True, 'chat_id': None, 'chat_record_id': None})
|
||||
else:
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
|
||||
def execute(self, model_id, system, prompt, dialogue_number, history_chat_record, stream, chat_id,
|
||||
chat_record_id,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from typing import Type
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -25,6 +26,7 @@ class ApplicationNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IApplicationNode(INode):
|
||||
type = 'application-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return ApplicationNodeSerializer
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode
|
||||
|
||||
|
||||
|
|
@ -36,3 +37,5 @@ class IConditionNode(INode):
|
|||
return ConditionNodeParamsSerializer
|
||||
|
||||
type = 'condition-node'
|
||||
|
||||
support = [WorkflowMode.APPLICATION_LOOP]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -35,5 +36,7 @@ class IDataSourceLocalNode(INode):
|
|||
def _run(self):
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
|
||||
def execute(self, file_format, max_file_number, file_max_size, **kwargs) -> NodeResult:
|
||||
def execute(self, file_type_list, file_size_limit, file_count_limit, **kwargs) -> NodeResult:
|
||||
pass
|
||||
|
||||
support = [WorkflowMode.KNOWLEDGE]
|
||||
|
|
|
|||
|
|
@ -34,5 +34,6 @@ class BaseDataSourceLocalNode(IDataSourceLocalNode):
|
|||
'label': '',
|
||||
}]
|
||||
|
||||
def execute(self, file_format, max_file_number, file_max_size, **kwargs) -> NodeResult:
|
||||
pass
|
||||
def execute(self, file_type_list, file_size_limit, file_count_limit, **kwargs) -> NodeResult:
|
||||
return NodeResult({'file_list': self.workflow_manage.params.get('data_source', {}).get('file_list')},
|
||||
self.workflow_manage.params.get('knowledge_base') or {})
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@
|
|||
"""
|
||||
from abc import abstractmethod
|
||||
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
class IDataSourceWebNode(INode):
|
||||
|
||||
type = 'data-source-web-node'
|
||||
support = [WorkflowMode.KNOWLEDGE]
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
|
|
@ -24,7 +24,5 @@ class IDataSourceWebNode(INode):
|
|||
def _run(self):
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
|
||||
|
||||
def execute(self, **kwargs) -> NodeResult:
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from typing import Type
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
from common.exception.app_exception import AppApiException
|
||||
|
||||
|
|
@ -38,6 +39,8 @@ class ReplyNodeParamsSerializer(serializers.Serializer):
|
|||
|
||||
class IReplyNode(INode):
|
||||
type = 'reply-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP, WorkflowMode.KNOWLEDGE_LOOP,
|
||||
WorkflowMode.KNOWLEDGE]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return ReplyNodeParamsSerializer
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -14,7 +15,8 @@ class DocumentExtractNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IDocumentExtractNode(INode):
|
||||
type = 'document-extract-node'
|
||||
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP, WorkflowMode.KNOWLEDGE_LOOP,
|
||||
WorkflowMode.KNOWLEDGE]
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return DocumentExtractNodeSerializer
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from typing import Type
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -24,6 +25,7 @@ class FormNodeParamsSerializer(serializers.Serializer):
|
|||
class IFormNode(INode):
|
||||
type = 'form-node'
|
||||
view_type = 'single_view'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return FormNodeParamsSerializer
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ class ImageGenerateNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IImageGenerateNode(INode):
|
||||
type = 'image-generate-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return ImageGenerateNodeSerializer
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ class ImageToVideoNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IImageToVideoNode(INode):
|
||||
type = 'image-to-video-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return ImageToVideoNodeSerializer
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from typing import Type
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -30,6 +31,7 @@ class ImageUnderstandNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IImageUnderstandNode(INode):
|
||||
type = 'image-understand-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return ImageUnderstandNodeSerializer
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
class IntentBranchSerializer(serializers.Serializer):
|
||||
|
||||
id = serializers.CharField(required=True, label=_("Branch id"))
|
||||
content = serializers.CharField(required=True, label=_("content"))
|
||||
isOther = serializers.BooleanField(required=True, label=_("Branch Type"))
|
||||
|
|
@ -24,8 +24,11 @@ class IntentNodeSerializer(serializers.Serializer):
|
|||
label=_("Model parameter settings"))
|
||||
branch = IntentBranchSerializer(many=True)
|
||||
|
||||
|
||||
class IIntentNode(INode):
|
||||
type = 'intent-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def save_context(self, details, workflow_manage):
|
||||
pass
|
||||
|
||||
|
|
@ -38,9 +41,9 @@ class IIntentNode(INode):
|
|||
self.node_params_serializer.data.get('content_list')[1:],
|
||||
)
|
||||
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data, user_input=str(question))
|
||||
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data,
|
||||
user_input=str(question))
|
||||
|
||||
def execute(self, model_id, dialogue_number, history_chat_record, user_input, branch,
|
||||
model_params_setting=None, **kwargs) -> NodeResult:
|
||||
pass
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode
|
||||
from application.flow.i_step_node import NodeResult
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ class LoopBreakNodeSerializer(serializers.Serializer):
|
|||
|
||||
class ILoopBreakNode(INode):
|
||||
type = 'loop-break-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return LoopBreakNodeSerializer
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
"""
|
||||
from typing import Type
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class ConditionSerializer(serializers.Serializer):
|
||||
|
|
@ -27,6 +28,7 @@ class LoopContinueNodeSerializer(serializers.Serializer):
|
|||
|
||||
class ILoopContinueNode(INode):
|
||||
type = 'loop-continue-node'
|
||||
support = [WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return LoopContinueNodeSerializer
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
from common.exception.app_exception import AppApiException
|
||||
|
||||
|
|
@ -40,6 +41,7 @@ class ILoopNodeSerializer(serializers.Serializer):
|
|||
|
||||
class ILoopNode(INode):
|
||||
type = 'loop-node'
|
||||
support = [WorkflowMode.APPLICATION]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return ILoopNodeSerializer
|
||||
|
|
|
|||
|
|
@ -6,15 +6,16 @@
|
|||
@date:2024/6/3 16:54
|
||||
@desc:
|
||||
"""
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
class ILoopStarNode(INode):
|
||||
type = 'loop-start-node'
|
||||
support = [WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def _run(self):
|
||||
return self.execute(**self.flow_params_serializer.data)
|
||||
|
||||
def execute(self, **kwargs) -> NodeResult:
|
||||
def execute(self, **kwargs) -> NodeResult:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ class McpNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IMcpNode(INode):
|
||||
type = 'mcp-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return McpNodeSerializer
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -23,6 +24,8 @@ class VariableSplittingNodeParamsSerializer(serializers.Serializer):
|
|||
|
||||
class IParameterExtractionNode(INode):
|
||||
type = 'parameter-extraction-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP, WorkflowMode.KNOWLEDGE,
|
||||
WorkflowMode.KNOWLEDGE_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return VariableSplittingNodeParamsSerializer
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ class QuestionNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IQuestionNode(INode):
|
||||
type = 'question-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return QuestionNodeSerializer
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from typing import Type
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -41,6 +42,7 @@ class RerankerStepNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IRerankerNode(INode):
|
||||
type = 'reranker-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return RerankerStepNodeSerializer
|
||||
|
|
@ -57,6 +59,6 @@ class IRerankerNode(INode):
|
|||
|
||||
reranker_list=reranker_list)
|
||||
|
||||
def execute(self, question, reranker_setting, reranker_list, reranker_model_id,show_knowledge,
|
||||
def execute(self, question, reranker_setting, reranker_list, reranker_model_id, show_knowledge,
|
||||
**kwargs) -> NodeResult:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from typing import Type, List
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ class SearchDocumentStepNodeSerializer(serializers.Serializer):
|
|||
|
||||
class ISearchDocumentStepNode(INode):
|
||||
type = 'search-document-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return SearchDocumentStepNodeSerializer
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from django.core import validators
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
from common.utils.common import flat_map
|
||||
|
||||
|
|
@ -67,6 +68,7 @@ def get_paragraph_list(chat_record, node_id):
|
|||
|
||||
class ISearchKnowledgeStepNode(INode):
|
||||
type = 'search-knowledge-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return SearchDatasetStepNodeSerializer
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
from typing import Type
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class SpeechToTextNodeSerializer(serializers.Serializer):
|
||||
|
|
@ -22,6 +23,7 @@ class SpeechToTextNodeSerializer(serializers.Serializer):
|
|||
|
||||
class ISpeechToTextNode(INode):
|
||||
type = 'speech-to-text-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return SpeechToTextNodeSerializer
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@
|
|||
@date:2024/6/3 16:54
|
||||
@desc:
|
||||
"""
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
class IStarNode(INode):
|
||||
type = 'start-node'
|
||||
support = [WorkflowMode.APPLICATION]
|
||||
|
||||
def _run(self):
|
||||
return self.execute(**self.flow_params_serializer.data)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from typing import Type
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -22,6 +23,7 @@ class TextToSpeechNodeSerializer(serializers.Serializer):
|
|||
|
||||
class ITextToSpeechNode(INode):
|
||||
type = 'text-to-speech-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return TextToSpeechNodeSerializer
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ class TextToVideoNodeSerializer(serializers.Serializer):
|
|||
|
||||
class ITextToVideoNode(INode):
|
||||
type = 'text-to-video-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return TextToVideoNodeSerializer
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from django.db.models import QuerySet
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
from common.field.common import ObjectField
|
||||
from tools.models.tool import Tool
|
||||
|
|
@ -40,6 +41,7 @@ class FunctionLibNodeParamsSerializer(serializers.Serializer):
|
|||
|
||||
class IToolLibNode(INode):
|
||||
type = 'tool-lib-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return FunctionLibNodeParamsSerializer
|
||||
|
|
|
|||
|
|
@ -10,15 +10,15 @@ import re
|
|||
from typing import Type
|
||||
|
||||
from django.core import validators
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework.utils.formatting import lazy_format
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.field.common import ObjectField
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.utils.formatting import lazy_format
|
||||
|
||||
|
||||
class InputField(serializers.Serializer):
|
||||
name = serializers.CharField(required=True, label=_('Variable Name'))
|
||||
|
|
@ -53,6 +53,7 @@ class FunctionNodeParamsSerializer(serializers.Serializer):
|
|||
|
||||
class IToolNode(INode):
|
||||
type = 'tool-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return FunctionNodeParamsSerializer
|
||||
|
|
|
|||
|
|
@ -5,11 +5,10 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
||||
|
||||
class VariableListSerializer(serializers.Serializer):
|
||||
v_id = serializers.CharField(required=True, label=_("Variable id"))
|
||||
variable = serializers.ListField(required=True, label=_("Variable"))
|
||||
|
|
@ -29,15 +28,13 @@ class VariableAggregationNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IVariableAggregation(INode):
|
||||
type = 'variable-aggregation-node'
|
||||
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return VariableAggregationNodeSerializer
|
||||
|
||||
def _run(self):
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
|
||||
def execute(self,strategy,group_list,**kwargs) -> NodeResult:
|
||||
def execute(self, strategy, group_list, **kwargs) -> NodeResult:
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ class VariableAssignNodeParamsSerializer(serializers.Serializer):
|
|||
|
||||
class IVariableAssignNode(INode):
|
||||
type = 'variable-assign-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return VariableAssignNodeParamsSerializer
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from typing import Type
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
|
@ -18,6 +19,7 @@ class VariableSplittingNodeParamsSerializer(serializers.Serializer):
|
|||
|
||||
class IVariableSplittingNode(INode):
|
||||
type = 'variable-splitting-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return VariableSplittingNodeParamsSerializer
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
from typing import Type
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import WorkflowMode
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class VideoUnderstandNodeSerializer(serializers.Serializer):
|
||||
model_id = serializers.CharField(required=True, label=_("Model id"))
|
||||
|
|
@ -30,6 +30,7 @@ class VideoUnderstandNodeSerializer(serializers.Serializer):
|
|||
|
||||
class IVideoUnderstandNode(INode):
|
||||
type = 'video-understand-node'
|
||||
support = [WorkflowMode.APPLICATION, WorkflowMode.APPLICATION_LOOP]
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return VideoUnderstandNodeSerializer
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from rest_framework import status
|
|||
|
||||
from application.flow import tools
|
||||
from application.flow.common import Workflow
|
||||
from application.flow.i_step_node import INode, WorkFlowPostHandler, NodeResult
|
||||
from application.flow.i_step_node import INode, WorkFlowPostHandler, NodeResult, FlowParamsSerializer
|
||||
from application.flow.step_node import get_node
|
||||
from common.handle.base_to_response import BaseToResponse
|
||||
from common.handle.impl.response.system_to_response import SystemToResponse
|
||||
|
|
@ -302,8 +302,8 @@ class WorkflowManage:
|
|||
answer_tokens = sum([row.get('answer_tokens') for row in details.values() if
|
||||
'answer_tokens' in row and row.get('answer_tokens') is not None])
|
||||
self.work_flow_post_handler.handler(self)
|
||||
yield self.base_to_response.to_stream_chunk_response(self.params['chat_id'],
|
||||
self.params['chat_record_id'],
|
||||
yield self.base_to_response.to_stream_chunk_response(self.params.get('chat_id'),
|
||||
self.params.get('chat_record_id'),
|
||||
'',
|
||||
[],
|
||||
'', True, message_tokens, answer_tokens, {})
|
||||
|
|
@ -316,7 +316,7 @@ class WorkflowManage:
|
|||
translation.activate(language)
|
||||
if current_node is None:
|
||||
start_node = self.get_start_node()
|
||||
current_node = get_node(start_node.type)(start_node, self.params, self)
|
||||
current_node = get_node(start_node.type, self.flow.workflow_mode)(start_node, self.params, self)
|
||||
self.node_chunk_manage.add_node_chunk(current_node.node_chunk)
|
||||
# 添加节点
|
||||
self.append_node(current_node)
|
||||
|
|
@ -402,8 +402,8 @@ class WorkflowManage:
|
|||
node_type = r.get("node_type")
|
||||
view_type = r.get('view_type')
|
||||
reasoning_content = r.get('reasoning_content')
|
||||
chunk = self.base_to_response.to_stream_chunk_response(self.params['chat_id'],
|
||||
self.params['chat_record_id'],
|
||||
chunk = self.base_to_response.to_stream_chunk_response(self.params.get('chat_id'),
|
||||
self.params.get('chat_record_id'),
|
||||
current_node.id,
|
||||
current_node.up_node_id_list,
|
||||
content, False, 0, 0,
|
||||
|
|
@ -417,8 +417,8 @@ class WorkflowManage:
|
|||
'node_status': "SUCCESS"})
|
||||
current_node.node_chunk.add_chunk(chunk)
|
||||
chunk = (self.base_to_response
|
||||
.to_stream_chunk_response(self.params['chat_id'],
|
||||
self.params['chat_record_id'],
|
||||
.to_stream_chunk_response(self.params.get('chat_id'),
|
||||
self.params.get('chat_record_id'),
|
||||
current_node.id,
|
||||
current_node.up_node_id_list,
|
||||
'', False, 0, 0, {'node_is_end': True,
|
||||
|
|
@ -436,8 +436,8 @@ class WorkflowManage:
|
|||
except Exception as e:
|
||||
# 添加节点
|
||||
traceback.print_exc()
|
||||
chunk = self.base_to_response.to_stream_chunk_response(self.params['chat_id'],
|
||||
self.params['chat_record_id'],
|
||||
chunk = self.base_to_response.to_stream_chunk_response(self.params.get('chat_id'),
|
||||
self.params.get('chat_record_id'),
|
||||
current_node.id,
|
||||
current_node.up_node_id_list,
|
||||
'Exception:' + str(e), False, 0, 0,
|
||||
|
|
@ -698,8 +698,9 @@ class WorkflowManage:
|
|||
get_node_params=lambda node: node.properties.get('node_data')):
|
||||
for node in self.flow.nodes:
|
||||
if node.id == node_id:
|
||||
node_instance = get_node(node.type)(node,
|
||||
self.params, self, up_node_id_list, get_node_params)
|
||||
node_instance = get_node(node.type, self.flow.workflow_mode)(node,
|
||||
self.params, self, up_node_id_list,
|
||||
get_node_params)
|
||||
return node_instance
|
||||
return None
|
||||
|
||||
|
|
@ -712,3 +713,6 @@ class WorkflowManage:
|
|||
def get_node_reference(self, reference_address: Dict):
|
||||
node = self.get_node_by_id(reference_address.get('node_id'))
|
||||
return node.context[reference_address.get('node_field')]
|
||||
|
||||
def get_params_serializer_class(self):
|
||||
return FlowParamsSerializer
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ from django.db.models import QuerySet
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.common import Workflow, WorkflowMode
|
||||
from application.flow.i_step_node import KnowledgeWorkflowPostHandler
|
||||
from application.flow.knowledge_workflow_manage import KnowledgeWorkflowManage
|
||||
from application.flow.step_node import get_node
|
||||
from common.exception.app_exception import AppApiException
|
||||
from knowledge.models import KnowledgeScope, Knowledge, KnowledgeType, KnowledgeWorkflow
|
||||
|
|
@ -23,6 +26,23 @@ class KnowledgeWorkflowModelSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
|
||||
class KnowledgeWorkflowActionSerializer(serializers.Serializer):
|
||||
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
|
||||
knowledge_id = serializers.UUIDField(required=True, label=_('knowledge id'))
|
||||
|
||||
def action(self, instance: Dict, with_valid=True):
|
||||
if with_valid:
|
||||
self.is_valid(raise_exception=True)
|
||||
knowledge_workflow = QuerySet(KnowledgeWorkflow).filter(knowledge_id=self.data.get("knowledge_id")).first()
|
||||
work_flow_manage = KnowledgeWorkflowManage(
|
||||
Workflow.new_instance(knowledge_workflow.work_flow, WorkflowMode.KNOWLEDGE),
|
||||
{'knowledge_id': self.data.get("knowledge_id"), 'stream': True,
|
||||
**instance},
|
||||
KnowledgeWorkflowPostHandler(None))
|
||||
r = work_flow_manage.run()
|
||||
return r
|
||||
|
||||
|
||||
class KnowledgeWorkflowSerializer(serializers.Serializer):
|
||||
class Form(serializers.Serializer):
|
||||
type = serializers.CharField(required=True, label=_('type'))
|
||||
|
|
@ -32,7 +52,7 @@ class KnowledgeWorkflowSerializer(serializers.Serializer):
|
|||
def get_form_list(self):
|
||||
self.is_valid(raise_exception=True)
|
||||
if self.data.get('type') == 'local':
|
||||
node = get_node(self.data.get('id'))
|
||||
node = get_node(self.data.get('id'), WorkflowMode.KNOWLEDGE)
|
||||
return node.get_form_list(self.data.get("node"))
|
||||
elif self.data.get('type') == 'tool':
|
||||
tool = QuerySet(Tool).filter(id=self.data.get("id")).first()
|
||||
|
|
|
|||
|
|
@ -70,5 +70,6 @@ urlpatterns = [
|
|||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<int:current_page>/<int:page_size>', views.DocumentView.Page.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<int:current_page>/<int:page_size>', views.KnowledgeView.Page.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/form_list/<str:type>/<str:id>', views.KnowledgeWorkflowFormView.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/action', views.KnowledgeWorkflowActionView.as_view())
|
||||
|
||||
]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from common.log.log import log
|
|||
from common.result import result
|
||||
from knowledge.api.knowledge_workflow import KnowledgeWorkflowApi
|
||||
from knowledge.serializers.common import get_knowledge_operation_object
|
||||
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowSerializer
|
||||
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowSerializer, KnowledgeWorkflowActionSerializer
|
||||
|
||||
|
||||
class KnowledgeWorkflowFormView(APIView):
|
||||
|
|
@ -23,6 +23,14 @@ class KnowledgeWorkflowFormView(APIView):
|
|||
data={'type': type, 'id': id, 'node': request.data.get('node')}).get_form_list())
|
||||
|
||||
|
||||
class KnowledgeWorkflowActionView(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
def post(self, request: Request, workspace_id: str, knowledge_id: str):
|
||||
return KnowledgeWorkflowActionSerializer(
|
||||
data={'workspace_id': workspace_id, 'knowledge_id': knowledge_id}).action(request.data, True)
|
||||
|
||||
|
||||
class KnowledgeWorkflowView(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Result } from '@/request/Result'
|
||||
import { get, post, del, put, exportFile, exportExcel } from '@/request/index'
|
||||
import { type Ref } from 'vue'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
import type { Dict, pageRequest } from '@/api/type/common'
|
||||
import type { knowledgeData } from '@/api/type/knowledge'
|
||||
|
||||
import useStore from '@/stores'
|
||||
|
|
@ -330,6 +330,13 @@ const getKnowledgeWorkflowFormList: (
|
|||
) => {
|
||||
return post(`${prefix.value}/${knowledge_id}/form_list/${type}/${id}`, { node }, {}, loading)
|
||||
}
|
||||
const workflowAction: (
|
||||
knowledge_id: string,
|
||||
instance: Dict<any>,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (knowledge_id: string, instance, loading) => {
|
||||
return post(`${prefix.value}/${knowledge_id}/action`, instance, {}, loading)
|
||||
}
|
||||
|
||||
export default {
|
||||
getKnowledgeList,
|
||||
|
|
@ -356,4 +363,5 @@ export default {
|
|||
delMulTag,
|
||||
createWorkflowKnowledge,
|
||||
getKnowledgeWorkflowFormList,
|
||||
workflowAction,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<div v-loading="loading">
|
||||
<div class="update-info flex p-8-12 border-r-6 mb-16 w-full">
|
||||
<div class="mt-4">
|
||||
<AppIcon iconName="app-warning-colorful" style="font-size: 16px"></AppIcon>
|
||||
|
|
@ -69,12 +69,13 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, useAttrs, nextTick } from 'vue'
|
||||
import { computed, useAttrs, nextTick, inject, ref } from 'vue'
|
||||
import type { FormField } from '@/components/dynamics-form/type'
|
||||
import { MsgError } from '@/utils/message'
|
||||
import type { UploadFiles } from 'element-plus'
|
||||
import { filesize, getImgUrl, isRightType } from '@/utils/common'
|
||||
import { filesize, getImgUrl } from '@/utils/common'
|
||||
import { t } from '@/locales'
|
||||
const upload = inject('upload') as any
|
||||
const attrs = useAttrs() as any
|
||||
const props = withDefaults(defineProps<{ modelValue?: any; formField: FormField }>(), {
|
||||
modelValue: () => [],
|
||||
|
|
@ -87,6 +88,8 @@ const onExceed = () => {
|
|||
)
|
||||
}
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const fileArray = ref<any>([])
|
||||
const loading = ref<boolean>(false)
|
||||
// 上传on-change事件
|
||||
const fileHandleChange = (file: any, fileList: UploadFiles) => {
|
||||
//1、判断文件大小是否合法,文件限制不能大于100M
|
||||
|
|
@ -102,8 +105,12 @@ const fileHandleChange = (file: any, fileList: UploadFiles) => {
|
|||
fileList.splice(-1, 1)
|
||||
return false
|
||||
}
|
||||
|
||||
emit('update:modelValue', fileList)
|
||||
upload(file.raw, loading).then((ok: any) => {
|
||||
const split_path = ok.data.split('/')
|
||||
const file_id = split_path[split_path.length - 1]
|
||||
fileArray.value?.push({ name: file.name, file_id, size: file.size })
|
||||
emit('update:modelValue', fileArray.value)
|
||||
})
|
||||
}
|
||||
function deleteFile(index: number) {
|
||||
emit(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
:before-close="close"
|
||||
>
|
||||
<div style="width: 100%; height: 100%">
|
||||
<ActionVue :workflow="_workflow"></ActionVue>
|
||||
<ActionVue :workflow="_workflow" :knowledge_id="_knowledge_id"></ActionVue>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
|
@ -17,12 +17,14 @@ import ActionVue from '@/views/knowledge-workflow/component/action/index.vue'
|
|||
import { ref } from 'vue'
|
||||
const drawer = ref<boolean>(false)
|
||||
const _workflow = ref<any>(null)
|
||||
const _knowledge_id = ref<string>()
|
||||
const close = () => {
|
||||
drawer.value = false
|
||||
}
|
||||
const open = (workflow: any) => {
|
||||
const open = (workflow: any, knowledge_id: string) => {
|
||||
drawer.value = true
|
||||
_workflow.value = workflow
|
||||
_knowledge_id.value = knowledge_id
|
||||
}
|
||||
defineExpose({ close, open })
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
require-asterisk-position="right"
|
||||
>
|
||||
<template #default>
|
||||
<el-form-item prop="data_source" :rules="base_form_data_rule.data_source">
|
||||
<el-radio-group @change="sourceChange" v-model="base_form_data.data_source">
|
||||
<el-form-item prop="node_id" :rules="base_form_data_rule.node_id">
|
||||
<el-radio-group @change="sourceChange" v-model="base_form_data.node_id">
|
||||
<el-radio :value="node.id" border size="large" v-for="node in source_node_list">
|
||||
<div style="display: flex; align-items: center">
|
||||
<component
|
||||
|
|
@ -52,7 +52,7 @@ const props = defineProps<{
|
|||
}>()
|
||||
const loading = ref<boolean>(false)
|
||||
const dynamicsFormRef = ref<InstanceType<typeof DynamicsForm>>()
|
||||
const base_form_data = ref<{ data_source: string }>({ data_source: '' })
|
||||
const base_form_data = ref<{ node_id: string }>({ node_id: '' })
|
||||
const dynamics_form_data = ref<Dict<any>>({})
|
||||
const form_data = computed({
|
||||
get: () => {
|
||||
|
|
@ -82,7 +82,7 @@ const sourceChange = (node_id: string) => {
|
|||
})
|
||||
}
|
||||
const base_form_data_rule = ref<FormRules>({
|
||||
data_source: {
|
||||
node_id: {
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: '数据源必选',
|
||||
|
|
|
|||
|
|
@ -11,26 +11,35 @@
|
|||
<el-button v-if="base_form_list.length > 0 && active == 'data_source'" @click="next"
|
||||
>下一步</el-button
|
||||
>
|
||||
<el-button v-if="base_form_list.length > 0 ? active == 'knowledge_base' : true" type="primary"
|
||||
<el-button
|
||||
v-if="base_form_list.length > 0 ? active == 'knowledge_base' : true"
|
||||
@click="upload"
|
||||
type="primary"
|
||||
>Upload
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, ref, provide, type Ref } from 'vue'
|
||||
import DataSource from '@/views/knowledge-workflow/component/action/DataSource.vue'
|
||||
import applicationApi from '@/api/application/application'
|
||||
import KnowledgeBase from '@/views/knowledge-workflow/component/action/KnowledgeBase.vue'
|
||||
import { WorkflowType } from '@/enums/application'
|
||||
import KnowledgeApi from '@/api/knowledge/knowledge'
|
||||
provide('upload', (file: any, loading?: Ref<boolean>) => {
|
||||
return applicationApi.postUploadFile(file, props.knowledge_id, 'KNOWLEDGE', loading)
|
||||
})
|
||||
const ak = {
|
||||
data_source: DataSource,
|
||||
knowledge_base: KnowledgeBase,
|
||||
}
|
||||
const ActionRef = ref()
|
||||
const form_data = ref<any>()
|
||||
const form_data = ref<any>({})
|
||||
const active = ref<'data_source' | 'knowledge_base'>('data_source')
|
||||
const props = defineProps<{
|
||||
workflow: any
|
||||
knowledge_id: string
|
||||
}>()
|
||||
const base_form_list = computed(() => {
|
||||
const kBase = props.workflow?.nodes?.find((n: any) => n.type === WorkflowType.KnowledgeBase)
|
||||
|
|
@ -41,6 +50,7 @@ const base_form_list = computed(() => {
|
|||
})
|
||||
const next = () => {
|
||||
ActionRef.value.validate().then(() => {
|
||||
form_data.value[active.value] = ActionRef.value.get_data()
|
||||
active.value = 'knowledge_base'
|
||||
})
|
||||
}
|
||||
|
|
@ -49,5 +59,11 @@ const up = () => {
|
|||
active.value = 'data_source'
|
||||
})
|
||||
}
|
||||
const upload = () => {
|
||||
ActionRef.value.validate().then(() => {
|
||||
form_data.value[active.value] = ActionRef.value.get_data()
|
||||
KnowledgeApi.workflowAction(props.knowledge_id, form_data.value)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
|||
|
|
@ -393,8 +393,7 @@ const clickShowDebug = () => {
|
|||
...workflow.get_base_node()?.properties.node_data,
|
||||
work_flow: getGraphData(),
|
||||
}
|
||||
console.log('sss', DebugRef.value)
|
||||
DebugRef.value?.open(graphData)
|
||||
DebugRef.value?.open(graphData, id)
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
MsgError(e.toString())
|
||||
|
|
|
|||
Loading…
Reference in New Issue