mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
fix: Tools cannot be called in the workflow (#3516)
This commit is contained in:
parent
dc51cc1f2a
commit
6866ff03b3
|
|
@ -144,6 +144,8 @@ class FlowParamsSerializer(serializers.Serializer):
|
|||
|
||||
workspace_id = serializers.CharField(required=True, label="工作空间id")
|
||||
|
||||
application_id = serializers.CharField(required=True, label="应用id")
|
||||
|
||||
re_chat = serializers.BooleanField(required=True, label="换个答案")
|
||||
|
||||
debug = serializers.BooleanField(required=True, label="是否debug")
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ class InputField(serializers.Serializer):
|
|||
|
||||
|
||||
class FunctionLibNodeParamsSerializer(serializers.Serializer):
|
||||
tool_id = serializers.UUIDField(required=True, label=_('Library ID'))
|
||||
tool_lib_id = serializers.UUIDField(required=True, label=_('Library ID'))
|
||||
input_field_list = InputField(required=True, many=True)
|
||||
is_result = serializers.BooleanField(required=False,
|
||||
label=_('Whether to return content'))
|
||||
|
||||
def is_valid(self, *, raise_exception=False):
|
||||
super().is_valid(raise_exception=True)
|
||||
f_lib = QuerySet(Tool).filter(id=self.data.get('tool_id')).first()
|
||||
f_lib = QuerySet(Tool).filter(id=self.data.get('tool_lib_id')).first()
|
||||
if f_lib is None:
|
||||
raise Exception(_('The function has been deleted'))
|
||||
|
||||
|
|
@ -44,5 +44,5 @@ class IToolLibNode(INode):
|
|||
def _run(self):
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
|
||||
def execute(self, function_lib_id, input_field_list, **kwargs) -> NodeResult:
|
||||
def execute(self, tool_lib_id, input_field_list, **kwargs) -> NodeResult:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -15,10 +15,13 @@ from django.utils.translation import gettext as _
|
|||
|
||||
from application.flow.i_step_node import NodeResult
|
||||
from application.flow.step_node.tool_lib_node.i_tool_lib_node import IToolLibNode
|
||||
from common.database_model_manage.database_model_manage import DatabaseModelManage
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.utils.function_code import FunctionExecutor
|
||||
from common.utils.rsa_util import rsa_long_decrypt
|
||||
from maxkb.const import CONFIG
|
||||
from system_manage.models import AuthTargetType
|
||||
from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer
|
||||
from tools.models import Tool
|
||||
|
||||
function_executor = FunctionExecutor(CONFIG.get('SANDBOX'))
|
||||
|
|
@ -101,13 +104,14 @@ def convert_value(name: str, value, _type, is_required, source, node):
|
|||
value=value))
|
||||
|
||||
|
||||
def valid_function(function_lib, user_id):
|
||||
if function_lib is None:
|
||||
raise Exception(_('Function does not exist'))
|
||||
if function_lib.permission_type == 'PRIVATE' and str(function_lib.user_id) != str(user_id):
|
||||
raise Exception(_('No permission to use this function {name}').format(name=function_lib.name))
|
||||
if not function_lib.is_active:
|
||||
raise Exception(_('Function {name} is unavailable').format(name=function_lib.name))
|
||||
def valid_function(tool_lib, workspace_id):
|
||||
if tool_lib is None:
|
||||
raise Exception(_('Tool does not exist'))
|
||||
get_authorized_tool = DatabaseModelManage.get_model("get_authorized_tool")
|
||||
if tool_lib and tool_lib.workspace_id != workspace_id and get_authorized_tool is not None:
|
||||
tool_lib = get_authorized_tool(QuerySet(Tool).filter(id=tool_lib.id), workspace_id).first()
|
||||
if tool_lib is None:
|
||||
raise Exception(_("Tool does not exist"))
|
||||
|
||||
|
||||
class BaseToolLibNodeNode(IToolLibNode):
|
||||
|
|
@ -116,9 +120,10 @@ class BaseToolLibNodeNode(IToolLibNode):
|
|||
if self.node_params.get('is_result'):
|
||||
self.answer_text = str(details.get('result'))
|
||||
|
||||
def execute(self, function_lib_id, input_field_list, **kwargs) -> NodeResult:
|
||||
function_lib = QuerySet(Tool).filter(id=function_lib_id).first()
|
||||
valid_function(function_lib, self.flow_params_serializer.data.get('user_id'))
|
||||
def execute(self, tool_lib_id, input_field_list, **kwargs) -> NodeResult:
|
||||
workspace_id = self.workflow_manage.get_body().get('workspace_id')
|
||||
tool_lib = QuerySet(Tool).filter(id=tool_lib_id).first()
|
||||
valid_function(tool_lib, workspace_id)
|
||||
params = {field.get('name'): convert_value(field.get('name'), field.get('value'), field.get('type'),
|
||||
field.get('is_required'),
|
||||
field.get('source'), self)
|
||||
|
|
@ -126,15 +131,15 @@ class BaseToolLibNodeNode(IToolLibNode):
|
|||
[{'value': get_field_value(input_field_list, field.get('name'), field.get('is_required'),
|
||||
), **field}
|
||||
for field in
|
||||
function_lib.input_field_list]}
|
||||
tool_lib.input_field_list]}
|
||||
|
||||
self.context['params'] = params
|
||||
# 合并初始化参数
|
||||
if function_lib.init_params is not None:
|
||||
all_params = json.loads(rsa_long_decrypt(function_lib.init_params)) | params
|
||||
if tool_lib.init_params is not None:
|
||||
all_params = json.loads(rsa_long_decrypt(tool_lib.init_params)) | params
|
||||
else:
|
||||
all_params = params
|
||||
result = function_executor.exec_code(function_lib.code, all_params)
|
||||
result = function_executor.exec_code(tool_lib.code, all_params)
|
||||
return NodeResult({'result': result}, {}, _write_context=write_context)
|
||||
|
||||
def get_details(self, index: int, **kwargs):
|
||||
|
|
|
|||
|
|
@ -237,7 +237,8 @@ class ChatSerializers(serializers.Serializer):
|
|||
'chat_user_type': chat_user_type,
|
||||
'workspace_id': workspace_id,
|
||||
'debug': debug,
|
||||
'chat_user': chat_info.get_chat_user()},
|
||||
'chat_user': chat_info.get_chat_user(),
|
||||
'application_id': chat_info.application_id},
|
||||
WorkFlowPostHandler(chat_info),
|
||||
base_to_response, form_data, image_list, document_list, audio_list,
|
||||
other_list,
|
||||
|
|
|
|||
|
|
@ -103,6 +103,33 @@ class UserResourcePermissionSerializer(serializers.Serializer):
|
|||
auth_target_type=self.data.get('auth_target_type'))
|
||||
}
|
||||
|
||||
def is_auth(self, resource_id: str):
|
||||
self.is_valid(raise_exception=True)
|
||||
auth_target_type = self.data.get('auth_target_type')
|
||||
workspace_id = self.data.get('workspace_id')
|
||||
user_id = self.data.get('user_id')
|
||||
workspace_manage = is_workspace_manage(user_id, workspace_id)
|
||||
if workspace_manage:
|
||||
return True
|
||||
wurp = QuerySet(WorkspaceUserResourcePermission).filter(auth_target_type=auth_target_type,
|
||||
workspace_id=workspace_id, user=user_id,
|
||||
target=resource_id).first()
|
||||
if wurp is None:
|
||||
return False
|
||||
workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping")
|
||||
role_permission_mapping_model = DatabaseModelManage.get_model("role_permission_mapping_model")
|
||||
|
||||
if wurp.auth_type == ResourceAuthType.ROLE.value:
|
||||
if workspace_user_role_mapping_model and role_permission_mapping_model:
|
||||
inner = QuerySet(workspace_user_role_mapping_model).filter(workspace_id=workspace_id, user_id=user_id)
|
||||
return QuerySet(role_permission_mapping_model).filter(role_id__in=inner,
|
||||
permission_id=(
|
||||
auth_target_type + ':READ')).exists()
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return wurp.permission_list.__contains__(ResourcePermission.VIEW.value)
|
||||
|
||||
def auth_resource(self, resource_id: str):
|
||||
self.is_valid(raise_exception=True)
|
||||
auth_target_type = self.data.get('auth_target_type')
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ import { Result } from '@/request/Result'
|
|||
import { get, post, del, put, exportFile } from '@/request/index'
|
||||
import { type Ref } from 'vue'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
import type {AddInternalToolParam, toolData} from '@/api/type/tool'
|
||||
|
||||
import type { AddInternalToolParam, toolData } from '@/api/type/tool'
|
||||
|
||||
import useStore from '@/stores'
|
||||
const prefix: any = { _value: '/workspace/' }
|
||||
|
|
@ -18,10 +17,10 @@ Object.defineProperty(prefix, 'value', {
|
|||
* 工具列表带分页(无分页)
|
||||
* @params 参数 {folder_id: string}
|
||||
*/
|
||||
const getToolList: (data?: any, loading?: Ref<boolean>) => Promise<Result<{tools: any[], folders: any[]}>> = (
|
||||
data,
|
||||
loading,
|
||||
) => {
|
||||
const getToolList: (
|
||||
data?: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<{ tools: any[]; folders: any[] }>> = (data, loading) => {
|
||||
return get(`${prefix.value}`, data, loading)
|
||||
}
|
||||
|
||||
|
|
@ -83,18 +82,18 @@ const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<a
|
|||
* 删除工具
|
||||
* @param 参数 tool_id
|
||||
*/
|
||||
const delTool: (
|
||||
tool_id: string,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<boolean>> = (tool_id, loading) => {
|
||||
const delTool: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||
tool_id,
|
||||
loading,
|
||||
) => {
|
||||
return del(`${prefix.value}/${tool_id}`, undefined, {}, loading)
|
||||
}
|
||||
|
||||
const putToolIcon: (
|
||||
id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (id, data, loading) => {
|
||||
const putToolIcon: (id: string, data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
id,
|
||||
data,
|
||||
loading,
|
||||
) => {
|
||||
return put(`${prefix.value}/${id}/edit_icon`, data, undefined, loading)
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +138,6 @@ const addInternalTool: (
|
|||
return post(`${prefix.value}/${tool_id}/add_internal_tool`, param, undefined, loading)
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
getToolList,
|
||||
getToolListPage,
|
||||
|
|
@ -152,5 +150,5 @@ export default {
|
|||
exportTool,
|
||||
putToolIcon,
|
||||
delTool,
|
||||
addInternalTool
|
||||
addInternalTool,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue