fix: add scope parameter to tool serializer in tool.py

This commit is contained in:
CaptainB 2025-06-19 18:33:15 +08:00
parent fd73ede7c8
commit 317db5ae18
4 changed files with 164 additions and 12 deletions

View File

@ -5,7 +5,7 @@ from drf_spectacular.utils import OpenApiParameter
from common.mixins.api_mixin import APIMixin
from common.result import ResultSerializer, DefaultResultSerializer
from tools.serializers.tool import ToolModelSerializer, ToolCreateRequest, ToolDebugRequest, ToolEditRequest, \
PylintInstance
PylintInstance, AddInternalToolRequest
class ToolCreateResponse(ResultSerializer):
@ -274,4 +274,51 @@ class EditIconAPI(APIMixin):
@staticmethod
def get_response():
return DefaultResultSerializer
return DefaultResultSerializer
class GetInternalToolAPI(APIMixin):
@staticmethod
def get_parameters():
return [
OpenApiParameter(
name="name",
description="工具名称",
type=OpenApiTypes.STR,
location='query',
required=False,
)
]
@staticmethod
def get_response():
return DefaultResultSerializer()
class AddInternalToolAPI(APIMixin):
@staticmethod
def get_request():
return AddInternalToolRequest
@staticmethod
def get_response():
return DefaultResultSerializer
@staticmethod
def get_parameters():
return [
OpenApiParameter(
name="workspace_id",
description="工作空间id",
type=OpenApiTypes.STR,
location='path',
required=True,
),
OpenApiParameter(
name="tool_id",
description="工具id",
type=OpenApiTypes.STR,
location='path',
required=True,
),
]

View File

@ -24,7 +24,7 @@ from common.utils.rsa_util import rsa_long_decrypt, rsa_long_encrypt
from common.utils.tool_code import ToolExecutor
from knowledge.models import File, FileSourceType
from maxkb.const import CONFIG, PROJECT_DIR
from tools.models import Tool, ToolScope, ToolFolder
from tools.models import Tool, ToolScope, ToolFolder, ToolType
from tools.serializers.tool_folder import ToolFolderFlatSerializer
tool_executor = ToolExecutor(CONFIG.get('SANDBOX'))
@ -157,14 +157,19 @@ class ToolCreateRequest(serializers.Serializer):
class ToolEditRequest(serializers.Serializer):
name = serializers.CharField(required=False, label=_('tool name'), allow_null=True)
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('tool description'))
code = serializers.CharField(required=False, label=_('tool content'), allow_null=True,)
code = serializers.CharField(required=False, label=_('tool content'), allow_null=True, )
input_field_list = serializers.ListField(required=False, default=list, allow_null=True, label=_('input field list'))
init_field_list = serializers.ListField(required=False, default=list, allow_null=True, label=_('init field list'))
init_params = serializers.DictField(required=False, default=dict, allow_null=True, label=_('init params'))
is_active = serializers.BooleanField(required=False, label=_('Is active'), allow_null=True,)
is_active = serializers.BooleanField(required=False, label=_('Is active'), allow_null=True, )
folder_id = serializers.CharField(required=False, allow_null=True)
class AddInternalToolRequest(serializers.Serializer):
name = serializers.CharField(required=False, label=_("tool name"), allow_null=True, allow_blank=True)
folder_id = serializers.CharField(required=False, allow_null=True, label=_("folder id"))
class DebugField(serializers.Serializer):
name = serializers.CharField(required=True, label=_('variable name'))
value = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_('variable value'))
@ -420,6 +425,59 @@ class ToolSerializer(serializers.Serializer):
return tool.icon
class InternalTool(serializers.Serializer):
user_id = serializers.UUIDField(required=True, label=_("User ID"))
name = serializers.CharField(required=False, label=_("tool name"), allow_null=True, allow_blank=True)
def get_internal_tools(self):
self.is_valid(raise_exception=True)
query_set = QuerySet(Tool)
if self.data.get('name', '') != '':
query_set = query_set.filter(
Q(name__icontains=self.data.get('name')) |
Q(desc__icontains=self.data.get('name'))
)
query_set = query_set.filter(
Q(scope=ToolScope.INTERNAL) &
Q(is_active=True)
)
return ToolModelSerializer(query_set, many=True).data
class AddInternalTool(serializers.Serializer):
user_id = serializers.UUIDField(required=True, label=_("User ID"))
workspace_id = serializers.CharField(required=True, label=_("workspace id"))
tool_id = serializers.UUIDField(required=True, label=_("tool id"))
def add(self, instance, with_valid=True):
if with_valid:
self.is_valid(raise_exception=True)
AddInternalToolRequest(data=instance).is_valid(raise_exception=True)
internal_tool = QuerySet(Tool).filter(id=self.data.get('tool_id')).first()
if internal_tool is None:
raise AppApiException(500, _('Tool does not exist'))
tool = Tool(
id=uuid.uuid7(),
name=instance.get('name', internal_tool.name),
desc=internal_tool.desc,
code=internal_tool.code,
user_id=self.data.get('user_id'),
workspace_id=self.data.get('workspace_id'),
input_field_list=internal_tool.input_field_list,
init_field_list=internal_tool.init_field_list,
scope=ToolScope.WORKSPACE,
tool_type=ToolType.CUSTOM,
folder_id=instance.get('folder_id', self.data.get('workspace_id')),
is_active=False
)
tool.save()
return ToolModelSerializer(tool).data
class ToolTreeSerializer(serializers.Serializer):
workspace_id = serializers.CharField(required=True, label=_('workspace id'))

View File

@ -4,6 +4,7 @@ from . import views
app_name = "tool"
urlpatterns = [
path('workspace/internal/tool', views.ToolView.InternalTool.as_view()),
path('workspace/<str:workspace_id>/tool', views.ToolView.as_view()),
path('workspace/<str:workspace_id>/tool/import', views.ToolView.Import.as_view()),
path('workspace/<str:workspace_id>/tool/pylint', views.ToolView.Pylint.as_view()),
@ -11,5 +12,6 @@ urlpatterns = [
path('workspace/<str:workspace_id>/tool/<str:tool_id>', views.ToolView.Operate.as_view()),
path('workspace/<str:workspace_id>/tool/<str:tool_id>/edit_icon', views.ToolView.EditIcon.as_view()),
path('workspace/<str:workspace_id>/tool/<str:tool_id>/export', views.ToolView.Export.as_view()),
path('workspace/<str:workspace_id>/tool/<str:tool_id>/add_internal_tool', views.ToolView.AddInternalTool.as_view()),
path('workspace/<str:workspace_id>/tool/<int:current_page>/<int:page_size>', views.ToolView.Page.as_view()),
]

View File

@ -11,7 +11,7 @@ from common.constants.permission_constants import PermissionConstants, RoleConst
from common.log.log import log
from common.result import result
from tools.api.tool import ToolCreateAPI, ToolEditAPI, ToolReadAPI, ToolDeleteAPI, ToolTreeReadAPI, ToolDebugApi, \
ToolExportAPI, ToolImportAPI, ToolPageAPI, PylintAPI, EditIconAPI
ToolExportAPI, ToolImportAPI, ToolPageAPI, PylintAPI, EditIconAPI, GetInternalToolAPI, AddInternalToolAPI
from tools.models import ToolScope, Tool
from tools.serializers.tool import ToolSerializer, ToolTreeSerializer
@ -44,7 +44,7 @@ class ToolView(APIView):
)
@log(
menu="Tool", operate="Create tool",
get_operation_object=lambda r, k: r.data.get('name'),
get_operation_object=lambda r, k: r.data.get('name'),
)
def post(self, request: Request, workspace_id: str):
return result.success(ToolSerializer.Create(
@ -110,7 +110,7 @@ class ToolView(APIView):
@log(
menu='Tool', operate='Update tool',
get_operation_object=lambda r, k: get_tool_operation_object(k.get('tool_id')),
)
def put(self, request: Request, workspace_id: str, tool_id: str):
return result.success(ToolSerializer.Operate(
@ -152,7 +152,7 @@ class ToolView(APIView):
@log(
menu='Tool', operate="Delete tool",
get_operation_object=lambda r, k: get_tool_operation_object(k.get('tool_id')),
)
def delete(self, request: Request, workspace_id: str, tool_id: str):
return result.success(ToolSerializer.Operate(
@ -227,9 +227,8 @@ class ToolView(APIView):
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
)
@log(
menu='Tool', operate="Export function",
get_operation_object=lambda r, k: get_tool_operation_object(k.get('id')),
menu='Tool', operate="Export tool",
get_operation_object=lambda r, k: get_tool_operation_object(k.get('tool_id')),
)
def get(self, request: Request, tool_id: str, workspace_id: str):
return ToolSerializer.Operate(
@ -284,3 +283,49 @@ class ToolView(APIView):
'user_id': request.user.id,
'image': request.FILES.get('file')
}).edit(request.data))
class InternalTool(APIView):
authentication_classes = [TokenAuth]
@extend_schema(
methods=['GET'],
description=_("Get internal tool"),
summary=_("Get internal tool"),
operation_id=_("Get internal tool"), # type: ignore
parameters=GetInternalToolAPI.get_parameters(),
responses=GetInternalToolAPI.get_response(),
tags=[_("Tool")] # type: ignore
)
def get(self, request: Request):
return result.success(ToolSerializer.InternalTool(data={
'user_id': request.user.id,
'name': request.query_params.get('name', ''),
}).get_internal_tools())
class AddInternalTool(APIView):
authentication_classes = [TokenAuth]
@extend_schema(
methods=['POST'],
description=_("Add internal tool"),
summary=_("Add internal tool"),
operation_id=_("Add internal tool"), # type: ignore
parameters=AddInternalToolAPI.get_parameters(),
request=AddInternalToolAPI.get_request(),
responses=AddInternalToolAPI.get_response(),
tags=[_("Tool")] # type: ignore
)
@has_permissions(
PermissionConstants.TOOL_CREATE.get_workspace_permission(),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
)
@log(
menu='Tool', operate="Add internal tool",
get_operation_object=lambda r, k: get_tool_operation_object(k.get('tool_id')),
)
def post(self, request: Request, tool_id: str, workspace_id: str):
return result.success(ToolSerializer.AddInternalTool(data={
'tool_id': tool_id,
'user_id': request.user.id,
'workspace_id': workspace_id
}).add(request.data))