mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-25 17:22:55 +00:00
feat: Knowledge workflow import and export
This commit is contained in:
parent
4fecd47904
commit
fd7204f044
|
|
@ -406,6 +406,9 @@ Permission_Label = {
|
|||
Group.SYSTEM_RES_APPLICATION_ACCESS.value: _("Application Access"),
|
||||
Group.SYSTEM_RES_APPLICATION_CHAT_USER.value: _("Dialogue users"),
|
||||
Group.SYSTEM_RES_APPLICATION_CHAT_LOG.value: _("Conversation log"),
|
||||
Group.APPLICATION_FOLDER.value: _("Folder"),
|
||||
Group.KNOWLEDGE_FOLDER.value: _("Folder"),
|
||||
Group.TOOL_FOLDER.value: _("Folder"),
|
||||
# SystemGroup.RESOURCE.value: _("Resource"),
|
||||
}
|
||||
|
||||
|
|
@ -468,31 +471,6 @@ class PermissionConstants(Enum):
|
|||
TOOL = Permission(
|
||||
group=Group.TOOL, operate=Operate.SELF, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
)
|
||||
APPLICATION_FOLDER_READ = Permission(
|
||||
group=Group.APPLICATION_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_VIEW]
|
||||
)
|
||||
APPLICATION_FOLDER_EDIT = Permission(
|
||||
group=Group.APPLICATION_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
|
||||
)
|
||||
KNOWLEDGE_FOLDER_READ = Permission(
|
||||
group=Group.KNOWLEDGE_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW]
|
||||
)
|
||||
KNOWLEDGE_FOLDER_EDIT = Permission(
|
||||
group=Group.KNOWLEDGE_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE]
|
||||
)
|
||||
TOOL_FOLDER_READ = Permission(
|
||||
group=Group.TOOL_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
|
||||
)
|
||||
TOOL_FOLDER_EDIT = Permission(
|
||||
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
|
||||
)
|
||||
|
||||
USER_READ = Permission(
|
||||
group=Group.USER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[SystemGroup.USER_MANAGEMENT]
|
||||
|
|
@ -578,6 +556,26 @@ class PermissionConstants(Enum):
|
|||
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
|
||||
)
|
||||
TOOL_FOLDER_READ = Permission(
|
||||
group=Group.TOOL_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
|
||||
)
|
||||
TOOL_FOLDER_CREATE = Permission(
|
||||
group=Group.TOOL_FOLDER, operate=Operate.CREATE, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
|
||||
)
|
||||
TOOL_FOLDER_EDIT = Permission(
|
||||
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
|
||||
)
|
||||
TOOL_FOLDER_DELETE = Permission(
|
||||
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
|
||||
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
|
||||
)
|
||||
KNOWLEDGE_READ = Permission(
|
||||
group=Group.KNOWLEDGE, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
|
||||
|
|
@ -623,6 +621,26 @@ class PermissionConstants(Enum):
|
|||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
||||
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||
)
|
||||
KNOWLEDGE_FOLDER_READ = Permission(
|
||||
group=Group.KNOWLEDGE_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
|
||||
parent_group = [WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||
)
|
||||
KNOWLEDGE_FOLDER_CREATE = Permission(
|
||||
group=Group.KNOWLEDGE_FOLDER, operate=Operate.CREATE, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
|
||||
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||
)
|
||||
KNOWLEDGE_FOLDER_EDIT = Permission(
|
||||
group=Group.KNOWLEDGE_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
||||
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||
)
|
||||
KNOWLEDGE_FOLDER_DELETE = Permission(
|
||||
group=Group.KNOWLEDGE_FOLDER, operate=Operate.DELETE, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
||||
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||
)
|
||||
KNOWLEDGE_WORKFLOW_READ = Permission(
|
||||
group=Group.KNOWLEDGE_WORKFLOW, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
|
||||
|
|
@ -633,6 +651,11 @@ class PermissionConstants(Enum):
|
|||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
||||
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||
)
|
||||
KNOWLEDGE_WORKFLOW_EXPORT = Permission(
|
||||
group=Group.KNOWLEDGE_WORKFLOW, operate=Operate.EXPORT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
|
||||
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
|
||||
)
|
||||
KNOWLEDGE_DOCUMENT_READ = Permission(
|
||||
group=Group.KNOWLEDGE_DOCUMENT, operate=Operate.READ,
|
||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
|
|
@ -926,6 +949,26 @@ class PermissionConstants(Enum):
|
|||
resource_permission_group_list=[
|
||||
ResourcePermissionConst.APPLICATION_MANGE],
|
||||
)
|
||||
APPLICATION_FOLDER_READ = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.READ,
|
||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_VIEW]
|
||||
)
|
||||
APPLICATION_FOLDER_CREATE = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.EDIT,
|
||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
|
||||
)
|
||||
APPLICATION_FOLDER_EDIT = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.EDIT,
|
||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
|
||||
)
|
||||
APPLICATION_FOLDER_DELETE = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.DELETE,
|
||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
|
||||
)
|
||||
APPLICATION_OVERVIEW_READ = Permission(group=Group.APPLICATION_OVERVIEW, operate=Operate.READ,
|
||||
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
|
||||
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
|
||||
|
|
|
|||
|
|
@ -298,7 +298,8 @@ ALLOWED_CLASSES = {
|
|||
("builtins", "dict"),
|
||||
('uuid', 'UUID'),
|
||||
("application.serializers.application", "MKInstance"),
|
||||
("tools.serializers.tool", "ToolInstance")
|
||||
("tools.serializers.tool", "ToolInstance"),
|
||||
("knowledge.serializers.knowledge_workflow", "KBWFInstance")
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ from drf_spectacular.types import OpenApiTypes
|
|||
from drf_spectacular.utils import OpenApiParameter
|
||||
|
||||
from common.mixins.api_mixin import APIMixin
|
||||
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowActionRequestSerializer
|
||||
from common.result import DefaultResultSerializer
|
||||
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowActionRequestSerializer, \
|
||||
KnowledgeWorkflowImportRequest
|
||||
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowActionListQuerySerializer
|
||||
|
||||
|
||||
|
|
@ -71,3 +73,39 @@ class KnowledgeWorkflowActionApi(APIMixin):
|
|||
required=True,
|
||||
)
|
||||
]
|
||||
|
||||
class KnowledgeWorkflowExportApi(APIMixin):
|
||||
@staticmethod
|
||||
def get_parameters():
|
||||
return [
|
||||
OpenApiParameter(
|
||||
name="workspace_id",
|
||||
description="工作空间id",
|
||||
type=OpenApiTypes.STR,
|
||||
location='path',
|
||||
required=True,
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="knowledge_id",
|
||||
description="知识库id",
|
||||
type=OpenApiTypes.STR,
|
||||
location='path',
|
||||
required=True,
|
||||
),
|
||||
]
|
||||
@staticmethod
|
||||
def get_response():
|
||||
return DefaultResultSerializer
|
||||
|
||||
class KnowledgeWorkflowImportApi(APIMixin):
|
||||
@staticmethod
|
||||
def get_parameters():
|
||||
return KnowledgeWorkflowExportApi.get_parameters()
|
||||
|
||||
@staticmethod
|
||||
def get_request():
|
||||
return KnowledgeWorkflowImportRequest
|
||||
|
||||
@staticmethod
|
||||
def get_response():
|
||||
return DefaultResultSerializer
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
# coding=utf-8
|
||||
import asyncio
|
||||
import json
|
||||
from typing import Dict
|
||||
import pickle
|
||||
from functools import reduce
|
||||
from typing import Dict, List
|
||||
|
||||
import uuid_utils.compat as uuid
|
||||
from django.db import transaction
|
||||
from django.db.models import QuerySet
|
||||
from django.http import HttpResponse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework import serializers, status
|
||||
|
||||
from application.flow.common import Workflow, WorkflowMode
|
||||
from application.flow.i_step_node import KnowledgeWorkflowPostHandler
|
||||
|
|
@ -18,6 +21,9 @@ from application.serializers.application import get_mcp_tools
|
|||
from common.constants.cache_version import Cache_Version
|
||||
from common.db.search import page_search
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.field.common import UploadedFileField
|
||||
from common.result import result
|
||||
from common.utils.common import restricted_loads, generate_uuid
|
||||
from common.utils.rsa_util import rsa_long_decrypt
|
||||
from common.utils.tool_code import ToolExecutor
|
||||
from knowledge.models import KnowledgeScope, Knowledge, KnowledgeType, KnowledgeWorkflow, KnowledgeWorkflowVersion
|
||||
|
|
@ -26,12 +32,22 @@ from knowledge.serializers.knowledge import KnowledgeModelSerializer
|
|||
from django.core.cache import cache
|
||||
from system_manage.models import AuthTargetType
|
||||
from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer
|
||||
from tools.models import Tool
|
||||
from tools.models import Tool, ToolScope
|
||||
from tools.serializers.tool import ToolExportModelSerializer
|
||||
from users.models import User
|
||||
|
||||
tool_executor = ToolExecutor()
|
||||
|
||||
|
||||
def hand_node(node, update_tool_map):
|
||||
if node.get('type') == 'tool-lib-node':
|
||||
tool_lib_id = (node.get('properties', {}).get('node_data', {}).get('tool_lib_id') or '')
|
||||
node.get('properties', {}).get('node_data', {})['tool_lib_id'] = update_tool_map.get(tool_lib_id, tool_lib_id)
|
||||
|
||||
if node.get('type') == 'search-knowledge-node':
|
||||
node.get('properties', {}).get('node_data', {})['knowledge_id_list'] = []
|
||||
|
||||
|
||||
class KnowledgeWorkflowModelSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = KnowledgeWorkflow
|
||||
|
|
@ -43,10 +59,24 @@ class KnowledgeWorkflowActionRequestSerializer(serializers.Serializer):
|
|||
knowledge_base = serializers.DictField(required=True, label=_('knowledge base data'))
|
||||
|
||||
|
||||
class KnowledgeWorkflowImportRequest(serializers.Serializer):
|
||||
file = UploadedFileField(required=True, label=_("file"))
|
||||
|
||||
|
||||
class KnowledgeWorkflowActionListQuerySerializer(serializers.Serializer):
|
||||
user_name = serializers.CharField(required=False, label=_('Name'), allow_blank=True, allow_null=True)
|
||||
state = serializers.CharField(required=False, label=_("State"), allow_blank=True, allow_null=True)
|
||||
|
||||
class KBWFInstance:
|
||||
|
||||
def __init__(self, knowledge_workflow: dict, function_lib_list: List[dict], version: str, tool_list: List[dict]):
|
||||
self.knowledge_workflow = knowledge_workflow
|
||||
self.function_lib_list = function_lib_list
|
||||
self.version = version
|
||||
self.tool_list = tool_list
|
||||
|
||||
def get_tool_list(self):
|
||||
return [*(self.tool_list or []), *(self.function_lib_list or [])]
|
||||
|
||||
class KnowledgeWorkflowActionSerializer(serializers.Serializer):
|
||||
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
|
||||
|
|
@ -217,6 +247,130 @@ class KnowledgeWorkflowSerializer(serializers.Serializer):
|
|||
|
||||
return {**KnowledgeModelSerializer(knowledge).data, 'document_list': []}
|
||||
|
||||
class Import(serializers.Serializer):
|
||||
user_id = serializers.UUIDField(required=True, label=_('user id'))
|
||||
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
|
||||
knowledge_id = serializers.UUIDField(required=True, label=_('knowledge id'))
|
||||
|
||||
def import_(self, instance: dict, is_import_tool, with_valid=True):
|
||||
if with_valid:
|
||||
self.is_valid()
|
||||
KnowledgeWorkflowImportRequest(data=instance).is_valid(raise_exception=True)
|
||||
user_id = self.data.get('user_id')
|
||||
workspace_id = self.data.get('workspace_id')
|
||||
knowledge_id = self.data.get('knowledge_id')
|
||||
kbwf_instance_bytes = instance.get('file').read()
|
||||
try:
|
||||
kbwf_instance = restricted_loads(kbwf_instance_bytes)
|
||||
except Exception as e:
|
||||
raise AppApiException(1001, _("Unsupported file format"))
|
||||
knowledge_workflow = kbwf_instance.knowledge_workflow
|
||||
tool_list = kbwf_instance.get_tool_list()
|
||||
update_tool_map = {}
|
||||
if len(tool_list) > 0:
|
||||
tool_id_list = reduce(lambda x, y: [*x, *y],
|
||||
[[tool.get('id'), generate_uuid((tool.get('id') + workspace_id or ''))]
|
||||
for tool
|
||||
in
|
||||
tool_list], [])
|
||||
# 存在的工具列表
|
||||
exits_tool_id_list = [str(tool.id) for tool in
|
||||
QuerySet(Tool).filter(id__in=tool_id_list, workspace_id=workspace_id)]
|
||||
# 需要更新的工具集合
|
||||
update_tool_map = {tool.get('id'): generate_uuid((tool.get('id') + workspace_id or '')) for tool
|
||||
in
|
||||
tool_list if
|
||||
not exits_tool_id_list.__contains__(
|
||||
tool.get('id'))}
|
||||
|
||||
tool_list = [{**tool, 'id': update_tool_map.get(tool.get('id'))} for tool in tool_list if
|
||||
not exits_tool_id_list.__contains__(
|
||||
tool.get('id')) and not exits_tool_id_list.__contains__(
|
||||
generate_uuid((tool.get('id') + workspace_id or '')))]
|
||||
|
||||
work_flow = self.to_knowledge_workflow(
|
||||
knowledge_workflow,
|
||||
update_tool_map,
|
||||
)
|
||||
tool_model_list = [self.to_tool(tool, workspace_id, user_id) for tool in tool_list]
|
||||
KnowledgeWorkflow.objects.filter(workspace_id=workspace_id,knowledge_id=knowledge_id).update(
|
||||
work_flow=work_flow
|
||||
)
|
||||
|
||||
if is_import_tool:
|
||||
if len(tool_model_list) > 0:
|
||||
QuerySet(Tool).bulk_create(tool_model_list)
|
||||
UserResourcePermissionSerializer(data={
|
||||
'workspace_id': self.data.get('workspace_id'),
|
||||
'user_id': self.data.get('user_id'),
|
||||
'auth_target_type': AuthTargetType.TOOL.value
|
||||
}).auth_resource_batch([t.id for t in tool_model_list])
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def to_knowledge_workflow(knowledge_workflow, update_tool_map):
|
||||
work_flow = knowledge_workflow.get("work_flow")
|
||||
for node in work_flow.get('nodes', []):
|
||||
hand_node(node, update_tool_map)
|
||||
if node.get('type') == 'loop_node':
|
||||
for n in node.get('properties', {}).get('node_data', {}).get('loop_body', {}).get('nodes', []):
|
||||
hand_node(n, update_tool_map)
|
||||
return work_flow
|
||||
|
||||
@staticmethod
|
||||
def to_tool(tool, workspace_id, user_id):
|
||||
return Tool(id=tool.get('id'),
|
||||
user_id=user_id,
|
||||
name=tool.get('name'),
|
||||
code=tool.get('code'),
|
||||
template_id=tool.get('template_id'),
|
||||
input_field_list=tool.get('input_field_list'),
|
||||
init_field_list=tool.get('init_field_list'),
|
||||
is_active=False if len((tool.get('init_field_list') or [])) > 0 else tool.get('is_active'),
|
||||
scope=ToolScope.WORKSPACE,
|
||||
folder_id=workspace_id,
|
||||
workspace_id=workspace_id)
|
||||
|
||||
class Export(serializers.Serializer):
|
||||
user_id = serializers.UUIDField(required=True, label=_('user id'))
|
||||
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
|
||||
knowledge_id = serializers.UUIDField(required=True, label=_('knowledge id'))
|
||||
|
||||
def export(self, with_valid=True):
|
||||
try:
|
||||
if with_valid:
|
||||
self.is_valid()
|
||||
knowledge_id = self.data.get('knowledge_id')
|
||||
knowledge_workflow = QuerySet(KnowledgeWorkflow).filter(knowledge_id=knowledge_id).first()
|
||||
knowledge = QuerySet(Knowledge).filter(id=knowledge_id).first()
|
||||
tool_id_list = [node.get('properties', {}).get('node_data', {}).get('tool_lib_id') for node
|
||||
in
|
||||
knowledge_workflow.work_flow.get('nodes', []) + reduce(lambda x, y: [*x, *y], [
|
||||
n.get('properties', {}).get('node_data', {}).get('loop_body', {}).get('nodes', [])
|
||||
for n
|
||||
in
|
||||
knowledge_workflow.work_flow.get('nodes', []) if n.get('type') == 'loop-node'], [])
|
||||
if
|
||||
node.get('type') == 'tool-lib-node']
|
||||
tool_list = []
|
||||
if len(tool_id_list) > 0:
|
||||
tool_list = QuerySet(Tool).filter(id__in=tool_id_list).exclude(scope=ToolScope.SHARED)
|
||||
knowledge_workflow_dict = KnowledgeWorkflowModelSerializer(knowledge_workflow).data
|
||||
|
||||
kbwf_instance = KBWFInstance(
|
||||
knowledge_workflow_dict,
|
||||
[],
|
||||
'v2',
|
||||
[ToolExportModelSerializer(tool).data for tool in tool_list]
|
||||
)
|
||||
knowledge_workflow_pickle = pickle.dumps(kbwf_instance)
|
||||
response = HttpResponse(content_type='text/plain', content=knowledge_workflow_pickle)
|
||||
response['Content-Disposition'] = f'attachment; filename="{knowledge.name}.kbwf"'
|
||||
return response
|
||||
except Exception as e:
|
||||
return result.error(str(e), response_status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
class Operate(serializers.Serializer):
|
||||
user_id = serializers.UUIDField(required=True, label=_('user id'))
|
||||
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ urlpatterns = [
|
|||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>', views.KnowledgeView.Operate.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/sync', views.KnowledgeView.SyncWeb.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow', views.KnowledgeWorkflowView.Operate.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow/export', views.KnowledgeWorkflowView.Export.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow/import', views.KnowledgeWorkflowView.Import.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/generate_related', views.KnowledgeView.GenerateRelated.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/embedding', views.KnowledgeView.Embedding.as_view()),
|
||||
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/hit_test', views.KnowledgeView.HitTest.as_view()),
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ from rest_framework.views import APIView
|
|||
|
||||
from application.api.application_api import SpeechToTextAPI
|
||||
from common.auth import TokenAuth
|
||||
from common.auth.authentication import has_permissions
|
||||
from common.auth.authentication import has_permissions, get_is_permissions
|
||||
from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
|
||||
from common.log.log import log
|
||||
from common.result import result, DefaultResultSerializer
|
||||
from knowledge.api.knowledge_workflow import KnowledgeWorkflowApi, KnowledgeWorkflowActionApi, \
|
||||
KnowledgeWorkflowActionPageApi
|
||||
KnowledgeWorkflowActionPageApi, KnowledgeWorkflowExportApi, KnowledgeWorkflowImportApi
|
||||
from knowledge.serializers.common import get_knowledge_operation_object
|
||||
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowSerializer, KnowledgeWorkflowActionSerializer, \
|
||||
KnowledgeWorkflowMcpSerializer
|
||||
|
|
@ -244,6 +244,73 @@ class KnowledgeWorkflowView(APIView):
|
|||
data={'knowledge_id': knowledge_id, 'user_id': request.user.id,
|
||||
'workspace_id': workspace_id, }).publish())
|
||||
|
||||
class Export(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
@extend_schema(
|
||||
methods=['GET'],
|
||||
description=_('Export knowledge workflow'),
|
||||
summary=_('Export knowledge workflow'),
|
||||
operation_id=_('Export knowledge workflow'), # type: ignore
|
||||
parameters=KnowledgeWorkflowExportApi.get_parameters(),
|
||||
request=None,
|
||||
responses=KnowledgeWorkflowExportApi.get_response(),
|
||||
tags=[_('Knowledge Base')] # type: ignore
|
||||
)
|
||||
@has_permissions(
|
||||
PermissionConstants.KNOWLEDGE_WORKFLOW_EXPORT.get_workspace_knowledge_permission(),
|
||||
PermissionConstants.KNOWLEDGE_WORKFLOW_EXPORT.get_workspace_permission_workspace_manage_role(),
|
||||
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
|
||||
ViewPermission(
|
||||
[RoleConstants.USER.get_workspace_role()],
|
||||
[PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()],
|
||||
CompareConstants.AND
|
||||
)
|
||||
)
|
||||
@log(menu='Knowledge', operate="Export knowledge workflow",
|
||||
get_operation_object=lambda r, k: get_knowledge_operation_object(k.get('knowledge_id')),
|
||||
)
|
||||
def get(self, request: Request, workspace_id: str, knowledge_id: str):
|
||||
return KnowledgeWorkflowSerializer.Export(
|
||||
data={'knowledge_id': knowledge_id,'user_id': request.user.id,'workspace_id': workspace_id}
|
||||
).export()
|
||||
|
||||
class Import(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
@extend_schema(
|
||||
methods=['POST'],
|
||||
description=_('Import knowledge workflow'),
|
||||
summary=_('Import knowledge workflow'),
|
||||
operation_id=_('Import knowledge workflow'), # type: ignore
|
||||
parameters=KnowledgeWorkflowImportApi.get_parameters(),
|
||||
request=KnowledgeWorkflowImportApi.get_request(),
|
||||
responses=KnowledgeWorkflowImportApi.get_response(),
|
||||
tags=[_('Knowledge Base')] # type: ignore
|
||||
)
|
||||
@has_permissions(
|
||||
PermissionConstants.KNOWLEDGE_WORKFLOW_EDIT.get_workspace_knowledge_permission(),
|
||||
PermissionConstants.KNOWLEDGE_WORKFLOW_EDIT.get_workspace_permission_workspace_manage_role(),
|
||||
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
|
||||
ViewPermission(
|
||||
[RoleConstants.USER.get_workspace_role()],
|
||||
[PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()],
|
||||
CompareConstants.AND
|
||||
)
|
||||
)
|
||||
@log(menu='Knowledge', operate="Import knowledge workflow",
|
||||
get_operation_object=lambda r, k: get_knowledge_operation_object(k.get('knowledge_id')),
|
||||
)
|
||||
def post(self, request: Request, workspace_id:str, knowledge_id: str):
|
||||
is_import_tool = get_is_permissions(request, workspace_id=workspace_id)(
|
||||
PermissionConstants.TOOL_IMPORT.get_workspace_permission(),
|
||||
PermissionConstants.TOOL_IMPORT.get_workspace_permission_workspace_manage_role(),
|
||||
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
|
||||
)
|
||||
return result.success(KnowledgeWorkflowSerializer.Import(data={
|
||||
'knowledge_id': knowledge_id, 'user_id': request.user.id, 'workspace_id': workspace_id
|
||||
}).import_({'file': request.FILES.get('file')}, is_import_tool))
|
||||
|
||||
class Operate(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
|
|
|
|||
|
|
@ -8874,4 +8874,10 @@ msgid "This account has been locked for %s minutes, please try again later"
|
|||
msgstr ""
|
||||
|
||||
msgid "User does not have permission to use API Key"
|
||||
msgstr ""
|
||||
|
||||
msgid "Import knowledge workflow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Export knowledge workflow"
|
||||
msgstr ""
|
||||
|
|
@ -9000,4 +9000,10 @@ msgid "This account has been locked for %s minutes, please try again later"
|
|||
msgstr "该账号已被锁定 %s 分钟,请稍后再试"
|
||||
|
||||
msgid "User does not have permission to use API Key"
|
||||
msgstr "用户没有使用 API Key 的权限"
|
||||
msgstr "用户没有使用 API Key 的权限"
|
||||
|
||||
msgid "Import knowledge workflow"
|
||||
msgstr "导入知识工作流"
|
||||
|
||||
msgid "Export knowledge workflow"
|
||||
msgstr "导出知识工作流"
|
||||
|
|
|
|||
|
|
@ -9001,3 +9001,9 @@ msgstr "該帳號已被鎖定 %s 分鐘,請稍後再試"
|
|||
|
||||
msgid "User does not have permission to use API Key"
|
||||
msgstr "使用者沒有使用 API Key 的權限"
|
||||
|
||||
msgid "Import knowledge workflow"
|
||||
msgstr "匯入知識工作流"
|
||||
|
||||
msgid "Export knowledge workflow"
|
||||
msgstr "匯出知識工作流"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import type { Dict, pageRequest } from '@/api/type/common'
|
|||
import type { knowledgeData } from '@/api/type/knowledge'
|
||||
|
||||
import useStore from '@/stores'
|
||||
import knowledge from '../system-shared/knowledge'
|
||||
const prefix: any = { _value: '/workspace/' }
|
||||
Object.defineProperty(prefix, 'value', {
|
||||
get: function () {
|
||||
|
|
@ -395,6 +396,37 @@ const putKnowledgeWorkflow: (
|
|||
return put(`${prefix.value}/${knowledge_id}/workflow`, data, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出知识库工作流
|
||||
* @param knowledge_id
|
||||
* @param knowledge_name
|
||||
* @param loading
|
||||
* @returns
|
||||
*/
|
||||
const exportKnowledgeWorkflow = (
|
||||
knowledge_id: string,
|
||||
knowledge_name: string,
|
||||
loading?: Ref<boolean>
|
||||
) => {
|
||||
return exportFile(
|
||||
knowledge_name + '.kbwf',
|
||||
`${prefix.value}/${knowledge_id}/workflow/export`,
|
||||
undefined,
|
||||
loading
|
||||
)
|
||||
}
|
||||
/**
|
||||
* 导入知识库工作流
|
||||
*/
|
||||
const importKnowledgeWorkflow: (
|
||||
knowledge_id: string,
|
||||
data: any,
|
||||
loading?:Ref<boolean>
|
||||
) => Promise<Result<any>> = (knowledge_id, data, loading)=>{
|
||||
return post(`${prefix.value}/${knowledge_id}/workflow/import`,data,undefined,loading)
|
||||
}
|
||||
|
||||
|
||||
const listKnowledgeVersion: (
|
||||
knowledge_id: string,
|
||||
loading?: Ref<boolean>,
|
||||
|
|
@ -487,4 +519,6 @@ export default {
|
|||
workflowUpload,
|
||||
getWorkflowActionPage,
|
||||
cancelWorkflowAction,
|
||||
exportKnowledgeWorkflow,
|
||||
importKnowledgeWorkflow
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,6 +197,12 @@ const systemManage = {
|
|||
PermissionConst.RESOURCE_KNOWLEDGE_WORKFLOW_EDIT
|
||||
],'OR'
|
||||
),
|
||||
workflow_export: () =>
|
||||
hasPermission([
|
||||
RoleConst.ADMIN,
|
||||
PermissionConst.RESOURCE_KNOWLEDGE_WORKFLOW_EXPORT
|
||||
],'OR'
|
||||
),
|
||||
chat_user_edit: () =>false,
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ const share = {
|
|||
hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_WORKFLOW_READ], 'OR'),
|
||||
workflow_edit: () =>
|
||||
hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_WORKFLOW_EDIT], 'OR'),
|
||||
|
||||
workflow_export: () =>
|
||||
hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_WORKFLOW_EXPORT], 'OR'),
|
||||
chat_user_edit: () => false,
|
||||
|
||||
auth: () => false,
|
||||
|
|
|
|||
|
|
@ -47,8 +47,9 @@ const workspaceShare = {
|
|||
folderAuth: () => false,
|
||||
folderDelete: () => false,
|
||||
hit_test: () => false,
|
||||
debug: () => true,
|
||||
workflow_edit: () => true,
|
||||
debug: () => false,
|
||||
workflow_edit: () => false,
|
||||
workflow_export: () => false,
|
||||
}
|
||||
|
||||
export default workspaceShare
|
||||
|
|
|
|||
|
|
@ -587,6 +587,21 @@ const workspace = {
|
|||
],
|
||||
'OR',
|
||||
),
|
||||
workflow_export: (source_id: string) =>
|
||||
hasPermission(
|
||||
[
|
||||
new ComplexPermission(
|
||||
[RoleConst.USER],
|
||||
[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],
|
||||
[],
|
||||
'AND',
|
||||
),
|
||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||
PermissionConst.KNOWLEDGE_WORKFLOW_EXPORT.getKnowledgeWorkspaceResourcePermission(source_id),
|
||||
PermissionConst.KNOWLEDGE_WORKFLOW_EXPORT.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
'OR',
|
||||
),
|
||||
hit_test: () => false,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ const PermissionConst = {
|
|||
|
||||
KNOWLEDGE_WORKFLOW_READ: new Permission('KNOWLEDGE_WORKFLOW:READ'),
|
||||
KNOWLEDGE_WORKFLOW_EDIT: new Permission('KNOWLEDGE_WORKFLOW:READ+EDIT'),
|
||||
KNOWLEDGE_WORKFLOW_EXPORT: new Permission('KNOWLEDGE_WORKFLOW:READ+EXPORT'),
|
||||
|
||||
KNOWLEDGE_DOCUMENT_READ: new Permission('KNOWLEDGE_DOCUMENT:READ'),
|
||||
KNOWLEDGE_DOCUMENT_CREATE: new Permission('KNOWLEDGE_DOCUMENT:READ+CREATE'),
|
||||
|
|
@ -196,6 +197,7 @@ const PermissionConst = {
|
|||
|
||||
SHARED_KNOWLEDGE_WORKFLOW_READ: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ'),
|
||||
SHARED_KNOWLEDGE_WORKFLOW_EDIT: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ+EDIT'),
|
||||
SHARED_KNOWLEDGE_WORKFLOW_EXPORT: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ+EXPORT'),
|
||||
|
||||
SHARED_KNOWLEDGE_DOCUMENT_READ: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ'),
|
||||
SHARED_KNOWLEDGE_DOCUMENT_CREATE: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ+CREATE'),
|
||||
|
|
@ -252,6 +254,7 @@ const PermissionConst = {
|
|||
|
||||
RESOURCE_KNOWLEDGE_WORKFLOW_READ: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_WORKFLOW:READ'),
|
||||
RESOURCE_KNOWLEDGE_WORKFLOW_EDIT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_WORKFLOW:READ+EDIT'),
|
||||
RESOURCE_KNOWLEDGE_WORKFLOW_EXPORT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_WORKFLOW:READ+EXPORT'),
|
||||
|
||||
RESOURCE_KNOWLEDGE_DOCUMENT_READ: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ'),
|
||||
RESOURCE_KNOWLEDGE_DOCUMENT_CREATE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ+CREATE'),
|
||||
|
|
|
|||
|
|
@ -52,6 +52,30 @@
|
|||
<AppIcon iconName="app-to-import-doc" class="color-secondary"></AppIcon>
|
||||
{{ $t('workflow.operation.toImportDoc') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click.stop="exportKnowledgeWorkflow(detail.name, detail.id)"
|
||||
v-if="permissionPrecise.workflow_export(id)"
|
||||
>
|
||||
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
|
||||
{{ $t('common.export') }}
|
||||
</el-dropdown-item>
|
||||
<el-upload
|
||||
class="import-button"
|
||||
ref="elUploadRef"
|
||||
:file-list="[]"
|
||||
action="#"
|
||||
multiple
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:limit="1"
|
||||
:on-change="(file: any, fileList: any) => importKnowledgeWorkflow(file)"
|
||||
v-if="permissionPrecise.workflow_edit(id)"
|
||||
>
|
||||
<el-dropdown-item>
|
||||
<AppIcon iconName="app-import" class="color-secondary"></AppIcon>
|
||||
{{ $t('common.import', '导入') }}
|
||||
</el-dropdown-item>
|
||||
</el-upload>
|
||||
<el-dropdown-item @click="openListAction" divided>
|
||||
<AppIcon iconName="app-execution-record" class="color-secondary"></AppIcon>
|
||||
{{ $t('workflow.ExecutionRecord') }}
|
||||
|
|
@ -366,6 +390,40 @@ const publish = () => {
|
|||
})
|
||||
}
|
||||
|
||||
const elUploadRef = ref()
|
||||
const importKnowledgeWorkflow = (file: any) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file.raw)
|
||||
elUploadRef.value.clearFiles()
|
||||
loadSharedApi({ type: 'knowledge', isShared: isShared.value, systemType: apiType.value })
|
||||
.importKnowledgeWorkflow(id, formData, loading)
|
||||
.then(() => {
|
||||
getDetail()
|
||||
})
|
||||
.catch((error: any) => {
|
||||
if (error.code === 400) {
|
||||
MsgConfirm(t('common.tip'), t('views.application.tip.professionalMessage'), {
|
||||
cancelButtonText: t('common.confirm'),
|
||||
confirmButtonText: t('common.professional'),
|
||||
}).then(() => {
|
||||
window.open('https://maxkb.cn/pricing.html', '_blank')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function exportKnowledgeWorkflow(name: string, id: string) {
|
||||
loadSharedApi({ type: 'knowledge', isShared: isShared.value, systemType: apiType.value })
|
||||
.exportKnowledgeWorkflow(id, name, loading)
|
||||
.catch((error: any) => {
|
||||
if (error.response.status !== 403) {
|
||||
error.response.data.text().then((res: string) => {
|
||||
MsgError(`${t('views.application.tip.ExportError')}:${JSON.parse(res).message}`)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const clickShowDebug = () => {
|
||||
workflowRef.value
|
||||
?.validate()
|
||||
|
|
|
|||
Loading…
Reference in New Issue