diff --git a/apps/application/flow/common.py b/apps/application/flow/common.py index 2ba944875..1b8d674f0 100644 --- a/apps/application/flow/common.py +++ b/apps/application/flow/common.py @@ -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) diff --git a/apps/application/flow/i_step_node.py b/apps/application/flow/i_step_node.py index 286b2b495..3ee7400b2 100644 --- a/apps/application/flow/i_step_node.py +++ b/apps/application/flow/i_step_node.py @@ -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 diff --git a/apps/application/flow/knowledge_workflow_manage.py b/apps/application/flow/knowledge_workflow_manage.py new file mode 100644 index 000000000..184ae3d10 --- /dev/null +++ b/apps/application/flow/knowledge_workflow_manage.py @@ -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] diff --git a/apps/application/flow/loop_workflow_manage.py b/apps/application/flow/loop_workflow_manage.py index cba38d320..7fc73c5f8 100644 --- a/apps/application/flow/loop_workflow_manage.py +++ b/apps/application/flow/loop_workflow_manage.py @@ -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 diff --git a/apps/application/flow/step_node/__init__.py b/apps/application/flow/step_node/__init__.py index dbca4e20c..b089f15ed 100644 --- a/apps/application/flow/step_node/__init__.py +++ b/apps/application/flow/step_node/__init__.py @@ -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) diff --git a/apps/application/flow/step_node/ai_chat_step_node/i_chat_node.py b/apps/application/flow/step_node/ai_chat_step_node/i_chat_node.py index 21e23f167..a7566bdac 100644 --- a/apps/application/flow/step_node/ai_chat_step_node/i_chat_node.py +++ b/apps/application/flow/step_node/ai_chat_step_node/i_chat_node.py @@ -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, diff --git a/apps/application/flow/step_node/application_node/i_application_node.py b/apps/application/flow/step_node/application_node/i_application_node.py index 5a4ea6e51..b41151ee3 100644 --- a/apps/application/flow/step_node/application_node/i_application_node.py +++ b/apps/application/flow/step_node/application_node/i_application_node.py @@ -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 diff --git a/apps/application/flow/step_node/condition_node/i_condition_node.py b/apps/application/flow/step_node/condition_node/i_condition_node.py index 1bd541b4c..305b260ef 100644 --- a/apps/application/flow/step_node/condition_node/i_condition_node.py +++ b/apps/application/flow/step_node/condition_node/i_condition_node.py @@ -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] diff --git a/apps/application/flow/step_node/data_source_local_node/i_data_source_local_node.py b/apps/application/flow/step_node/data_source_local_node/i_data_source_local_node.py index 856369d54..e6b39f686 100644 --- a/apps/application/flow/step_node/data_source_local_node/i_data_source_local_node.py +++ b/apps/application/flow/step_node/data_source_local_node/i_data_source_local_node.py @@ -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] diff --git a/apps/application/flow/step_node/data_source_local_node/impl/base_data_source_local_node.py b/apps/application/flow/step_node/data_source_local_node/impl/base_data_source_local_node.py index d64fdd861..24da15898 100644 --- a/apps/application/flow/step_node/data_source_local_node/impl/base_data_source_local_node.py +++ b/apps/application/flow/step_node/data_source_local_node/impl/base_data_source_local_node.py @@ -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 {}) diff --git a/apps/application/flow/step_node/data_source_web_node/i_data_source_web_node.py b/apps/application/flow/step_node/data_source_web_node/i_data_source_web_node.py index f5e210a8e..205304d9d 100644 --- a/apps/application/flow/step_node/data_source_web_node/i_data_source_web_node.py +++ b/apps/application/flow/step_node/data_source_web_node/i_data_source_web_node.py @@ -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 - diff --git a/apps/application/flow/step_node/direct_reply_node/i_reply_node.py b/apps/application/flow/step_node/direct_reply_node/i_reply_node.py index acb9262bd..4e530cb5c 100644 --- a/apps/application/flow/step_node/direct_reply_node/i_reply_node.py +++ b/apps/application/flow/step_node/direct_reply_node/i_reply_node.py @@ -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 diff --git a/apps/application/flow/step_node/document_extract_node/i_document_extract_node.py b/apps/application/flow/step_node/document_extract_node/i_document_extract_node.py index e907220ca..1b8b9c381 100644 --- a/apps/application/flow/step_node/document_extract_node/i_document_extract_node.py +++ b/apps/application/flow/step_node/document_extract_node/i_document_extract_node.py @@ -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 diff --git a/apps/application/flow/step_node/form_node/i_form_node.py b/apps/application/flow/step_node/form_node/i_form_node.py index 552434dbf..a47a75ddc 100644 --- a/apps/application/flow/step_node/form_node/i_form_node.py +++ b/apps/application/flow/step_node/form_node/i_form_node.py @@ -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 diff --git a/apps/application/flow/step_node/image_generate_step_node/i_image_generate_node.py b/apps/application/flow/step_node/image_generate_step_node/i_image_generate_node.py index 5ea2afad2..58eb191b4 100644 --- a/apps/application/flow/step_node/image_generate_step_node/i_image_generate_node.py +++ b/apps/application/flow/step_node/image_generate_step_node/i_image_generate_node.py @@ -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 diff --git a/apps/application/flow/step_node/image_to_video_step_node/i_image_to_video_node.py b/apps/application/flow/step_node/image_to_video_step_node/i_image_to_video_node.py index 5c408f6d4..eddeac426 100644 --- a/apps/application/flow/step_node/image_to_video_step_node/i_image_to_video_node.py +++ b/apps/application/flow/step_node/image_to_video_step_node/i_image_to_video_node.py @@ -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 diff --git a/apps/application/flow/step_node/image_understand_step_node/i_image_understand_node.py b/apps/application/flow/step_node/image_understand_step_node/i_image_understand_node.py index 1803fbea3..c7dd99ccb 100644 --- a/apps/application/flow/step_node/image_understand_step_node/i_image_understand_node.py +++ b/apps/application/flow/step_node/image_understand_step_node/i_image_understand_node.py @@ -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 diff --git a/apps/application/flow/step_node/intent_node/i_intent_node.py b/apps/application/flow/step_node/intent_node/i_intent_node.py index 0c48be9b9..487df0bdd 100644 --- a/apps/application/flow/step_node/intent_node/i_intent_node.py +++ b/apps/application/flow/step_node/intent_node/i_intent_node.py @@ -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 \ No newline at end of file + pass diff --git a/apps/application/flow/step_node/loop_break_node/i_loop_break_node.py b/apps/application/flow/step_node/loop_break_node/i_loop_break_node.py index d42d05a11..81792a014 100644 --- a/apps/application/flow/step_node/loop_break_node/i_loop_break_node.py +++ b/apps/application/flow/step_node/loop_break_node/i_loop_break_node.py @@ -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 diff --git a/apps/application/flow/step_node/loop_continue_node/i_loop_continue_node.py b/apps/application/flow/step_node/loop_continue_node/i_loop_continue_node.py index 07ee1252f..4dfe9426f 100644 --- a/apps/application/flow/step_node/loop_continue_node/i_loop_continue_node.py +++ b/apps/application/flow/step_node/loop_continue_node/i_loop_continue_node.py @@ -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 diff --git a/apps/application/flow/step_node/loop_node/i_loop_node.py b/apps/application/flow/step_node/loop_node/i_loop_node.py index 6b2176513..dacb57c2c 100644 --- a/apps/application/flow/step_node/loop_node/i_loop_node.py +++ b/apps/application/flow/step_node/loop_node/i_loop_node.py @@ -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 diff --git a/apps/application/flow/step_node/loop_start_node/i_loop_start_node.py b/apps/application/flow/step_node/loop_start_node/i_loop_start_node.py index 21a059b76..1995aa6fd 100644 --- a/apps/application/flow/step_node/loop_start_node/i_loop_start_node.py +++ b/apps/application/flow/step_node/loop_start_node/i_loop_start_node.py @@ -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 diff --git a/apps/application/flow/step_node/mcp_node/i_mcp_node.py b/apps/application/flow/step_node/mcp_node/i_mcp_node.py index cdd3f7e6a..0d8a19334 100644 --- a/apps/application/flow/step_node/mcp_node/i_mcp_node.py +++ b/apps/application/flow/step_node/mcp_node/i_mcp_node.py @@ -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 diff --git a/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py b/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py index 6ff670057..a0a9bc5cb 100644 --- a/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py +++ b/apps/application/flow/step_node/parameter_extraction_node/i_parameter_extraction_node.py @@ -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 diff --git a/apps/application/flow/step_node/question_node/i_question_node.py b/apps/application/flow/step_node/question_node/i_question_node.py index 74153bbfb..0835292d3 100644 --- a/apps/application/flow/step_node/question_node/i_question_node.py +++ b/apps/application/flow/step_node/question_node/i_question_node.py @@ -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 diff --git a/apps/application/flow/step_node/reranker_node/i_reranker_node.py b/apps/application/flow/step_node/reranker_node/i_reranker_node.py index d0164393d..0421c55b0 100644 --- a/apps/application/flow/step_node/reranker_node/i_reranker_node.py +++ b/apps/application/flow/step_node/reranker_node/i_reranker_node.py @@ -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 diff --git a/apps/application/flow/step_node/search_document_node/i_search_document_node.py b/apps/application/flow/step_node/search_document_node/i_search_document_node.py index 65eb87d96..2d55ef64b 100644 --- a/apps/application/flow/step_node/search_document_node/i_search_document_node.py +++ b/apps/application/flow/step_node/search_document_node/i_search_document_node.py @@ -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 diff --git a/apps/application/flow/step_node/search_knowledge_node/i_search_knowledge_node.py b/apps/application/flow/step_node/search_knowledge_node/i_search_knowledge_node.py index 7f9311e2d..17da82a4a 100644 --- a/apps/application/flow/step_node/search_knowledge_node/i_search_knowledge_node.py +++ b/apps/application/flow/step_node/search_knowledge_node/i_search_knowledge_node.py @@ -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 diff --git a/apps/application/flow/step_node/speech_to_text_step_node/i_speech_to_text_node.py b/apps/application/flow/step_node/speech_to_text_step_node/i_speech_to_text_node.py index 719e4201e..ba87a862b 100644 --- a/apps/application/flow/step_node/speech_to_text_step_node/i_speech_to_text_node.py +++ b/apps/application/flow/step_node/speech_to_text_step_node/i_speech_to_text_node.py @@ -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 diff --git a/apps/application/flow/step_node/start_node/i_start_node.py b/apps/application/flow/step_node/start_node/i_start_node.py index 41d73f218..40caf0199 100644 --- a/apps/application/flow/step_node/start_node/i_start_node.py +++ b/apps/application/flow/step_node/start_node/i_start_node.py @@ -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) diff --git a/apps/application/flow/step_node/text_to_speech_step_node/i_text_to_speech_node.py b/apps/application/flow/step_node/text_to_speech_step_node/i_text_to_speech_node.py index 539c8dbb5..1751a123c 100644 --- a/apps/application/flow/step_node/text_to_speech_step_node/i_text_to_speech_node.py +++ b/apps/application/flow/step_node/text_to_speech_step_node/i_text_to_speech_node.py @@ -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 diff --git a/apps/application/flow/step_node/text_to_video_step_node/i_text_to_video_node.py b/apps/application/flow/step_node/text_to_video_step_node/i_text_to_video_node.py index c91d70f59..39cb4393d 100644 --- a/apps/application/flow/step_node/text_to_video_step_node/i_text_to_video_node.py +++ b/apps/application/flow/step_node/text_to_video_step_node/i_text_to_video_node.py @@ -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 diff --git a/apps/application/flow/step_node/tool_lib_node/i_tool_lib_node.py b/apps/application/flow/step_node/tool_lib_node/i_tool_lib_node.py index 43a93cc3f..07408f1fb 100644 --- a/apps/application/flow/step_node/tool_lib_node/i_tool_lib_node.py +++ b/apps/application/flow/step_node/tool_lib_node/i_tool_lib_node.py @@ -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 diff --git a/apps/application/flow/step_node/tool_node/i_tool_node.py b/apps/application/flow/step_node/tool_node/i_tool_node.py index 2180efb77..286e44266 100644 --- a/apps/application/flow/step_node/tool_node/i_tool_node.py +++ b/apps/application/flow/step_node/tool_node/i_tool_node.py @@ -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 diff --git a/apps/application/flow/step_node/variable_aggregation_node/i_variable_aggregation_node.py b/apps/application/flow/step_node/variable_aggregation_node/i_variable_aggregation_node.py index d5a2f332a..b1de910c4 100644 --- a/apps/application/flow/step_node/variable_aggregation_node/i_variable_aggregation_node.py +++ b/apps/application/flow/step_node/variable_aggregation_node/i_variable_aggregation_node.py @@ -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 - - diff --git a/apps/application/flow/step_node/variable_assign_node/i_variable_assign_node.py b/apps/application/flow/step_node/variable_assign_node/i_variable_assign_node.py index 1eb21266c..87b8449d1 100644 --- a/apps/application/flow/step_node/variable_assign_node/i_variable_assign_node.py +++ b/apps/application/flow/step_node/variable_assign_node/i_variable_assign_node.py @@ -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 diff --git a/apps/application/flow/step_node/variable_splitting_node/i_variable_splitting_node.py b/apps/application/flow/step_node/variable_splitting_node/i_variable_splitting_node.py index 52cff8eb2..033a7477c 100644 --- a/apps/application/flow/step_node/variable_splitting_node/i_variable_splitting_node.py +++ b/apps/application/flow/step_node/variable_splitting_node/i_variable_splitting_node.py @@ -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 diff --git a/apps/application/flow/step_node/video_understand_step_node/i_video_understand_node.py b/apps/application/flow/step_node/video_understand_step_node/i_video_understand_node.py index 3266a8e0b..c6a4b8db4 100644 --- a/apps/application/flow/step_node/video_understand_step_node/i_video_understand_node.py +++ b/apps/application/flow/step_node/video_understand_step_node/i_video_understand_node.py @@ -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 diff --git a/apps/application/flow/workflow_manage.py b/apps/application/flow/workflow_manage.py index d35173ac9..78a458b64 100644 --- a/apps/application/flow/workflow_manage.py +++ b/apps/application/flow/workflow_manage.py @@ -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 diff --git a/apps/knowledge/serializers/knowledge_workflow.py b/apps/knowledge/serializers/knowledge_workflow.py index f449cc59d..9748f9757 100644 --- a/apps/knowledge/serializers/knowledge_workflow.py +++ b/apps/knowledge/serializers/knowledge_workflow.py @@ -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() diff --git a/apps/knowledge/urls.py b/apps/knowledge/urls.py index a4e686445..331539ed8 100644 --- a/apps/knowledge/urls.py +++ b/apps/knowledge/urls.py @@ -70,5 +70,6 @@ urlpatterns = [ path('workspace//knowledge//document//', views.DocumentView.Page.as_view()), path('workspace//knowledge//', views.KnowledgeView.Page.as_view()), path('workspace//knowledge//form_list//', views.KnowledgeWorkflowFormView.as_view()), + path('workspace//knowledge//action', views.KnowledgeWorkflowActionView.as_view()) ] diff --git a/apps/knowledge/views/knowledge_workflow.py b/apps/knowledge/views/knowledge_workflow.py index 7f902b135..c4b0fd1f6 100644 --- a/apps/knowledge/views/knowledge_workflow.py +++ b/apps/knowledge/views/knowledge_workflow.py @@ -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] diff --git a/ui/src/api/knowledge/knowledge.ts b/ui/src/api/knowledge/knowledge.ts index 4704afe9c..d7436e3f8 100644 --- a/ui/src/api/knowledge/knowledge.ts +++ b/ui/src/api/knowledge/knowledge.ts @@ -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, + loading?: Ref, +) => Promise> = (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, } diff --git a/ui/src/components/dynamics-form/items/upload/LocalFileUpload.vue b/ui/src/components/dynamics-form/items/upload/LocalFileUpload.vue index 2e92fa9ec..124a03efb 100644 --- a/ui/src/components/dynamics-form/items/upload/LocalFileUpload.vue +++ b/ui/src/components/dynamics-form/items/upload/LocalFileUpload.vue @@ -1,5 +1,5 @@ diff --git a/ui/src/views/knowledge-workflow/component/action/DataSource.vue b/ui/src/views/knowledge-workflow/component/action/DataSource.vue index ae4bcfd44..674fc0a25 100644 --- a/ui/src/views/knowledge-workflow/component/action/DataSource.vue +++ b/ui/src/views/knowledge-workflow/component/action/DataSource.vue @@ -9,8 +9,8 @@ require-asterisk-position="right" > diff --git a/ui/src/views/knowledge-workflow/index.vue b/ui/src/views/knowledge-workflow/index.vue index 91130dc67..86172110b 100644 --- a/ui/src/views/knowledge-workflow/index.vue +++ b/ui/src/views/knowledge-workflow/index.vue @@ -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())