diff --git a/apps/trigger/handler/impl/task/application_task.py b/apps/trigger/handler/impl/task/application_task.py index 6cbc7cdb8e3..bd34a69b19b 100644 --- a/apps/trigger/handler/impl/task/application_task.py +++ b/apps/trigger/handler/impl/task/application_task.py @@ -7,13 +7,15 @@ @desc: """ import json -from functools import reduce +import time +import traceback import uuid_utils.compat as uuid from django.db.models import QuerySet from application.models import ChatUserType, Chat, ChatRecord, ChatSourceChoices, Application from chat.serializers.chat import ChatSerializers +from common.utils.logger import maxkb_logger from knowledge.models.knowledge_action import State from trigger.handler.base_task import BaseTriggerTask from trigger.models import TaskRecord, TriggerTask @@ -30,9 +32,7 @@ def get_reference(fields, obj): def conversion_custom_value(value, _type): - if ['array', 'dict', 'float', 'int', 'boolean'].__contains__(_type): - return json.loads(value) - if _type == 'any': + if ['array', 'dict', 'float', 'int', 'boolean', 'any'].__contains__(_type): try: return json.loads(value) except Exception as e: @@ -86,7 +86,7 @@ def get_application_execute_parameters(parameter_setting, application_parameters _setting = setting.get(ck) if _setting: _value = get_field_value(_setting, kwargs, cv.get('type'), cv.get('required'), - cv.get('default_value'), cv.get('field')) + cv.get('default_value'), ck) parameters['form_data'][ck] = _value else: if cv.get('default_value'): @@ -96,7 +96,7 @@ def get_application_execute_parameters(parameter_setting, application_parameters raise Exception(f'{ck} is required') else: value = get_field_value(setting, kwargs, value.get('type'), value.get('required'), - value.get('default_value'), value.get('field')) + value.get('default_value'), key) parameters['message' if key == 'question' else key] = value else: if value.get('default_value'): @@ -145,7 +145,7 @@ def get_application_parameters_setting(application): else: base_node_list = [n for n in application.work_flow.get('nodes') if n.get('type') == "base-node"] if len(base_node_list) == 0: - raise Exception('错误的应用工作流信息') + raise Exception('Incorrect application workflow information') base_node = base_node_list[0] api_input_field_list = base_node.get('properties').get('api_input_field_list') or [] api_input_field_list = {user_field.get('variable'): { @@ -178,39 +178,43 @@ def support(self, trigger_task, **kwargs): def execute(self, trigger_task, **kwargs): parameter_setting = trigger_task.get('parameter') - application = QuerySet(Application).filter(id=trigger_task.get('source_id')).only('type', 'work_flow').first() - if application is None: - QuerySet(TriggerTask).filter(id=trigger_task.get('id')).delete() - return - application_parameters_setting = get_application_parameters_setting(application) - parameters = get_application_execute_parameters(parameter_setting, application_parameters_setting, kwargs) - parameters['re_chat'] = False - parameters['stream'] = True - chat_id = uuid.uuid7() - chat_user_id = str(uuid.uuid7()) - chat_record_id = str(uuid.uuid7()) - parameters['chat_record_id'] = chat_record_id - application_id = trigger_task.get('source_id') - message = parameters.get('message') - Chat.objects.get_or_create(id=chat_id, defaults={ - 'application_id': application_id, - 'abstract': message, - 'chat_user_id': chat_user_id, - 'chat_user_type': ChatUserType.ANONYMOUS_USER.value, - 'asker': {'username': "游客"}, - 'ip_address': kwargs.get('body')['ip_address'], - 'source': { - 'type': ChatSourceChoices.TRIGGER.value - }, - }) task_record_id = uuid.uuid7() - TaskRecord(id=task_record_id, trigger_id=trigger_task.get('trigger'), trigger_task_id=trigger_task.get('id'), - source_type="APPLICATION", - source_id=application_id, - task_record_id=chat_record_id, - meta={'chat_id': chat_id}, - state=State.STARTED).save() + start_time = time.time() try: + application = QuerySet(Application).filter(id=trigger_task.get('source_id')).only('type', + 'work_flow').first() + if application is None: + QuerySet(TriggerTask).filter(id=trigger_task.get('id')).delete() + return + application_id = trigger_task.get('source_id') + chat_id = uuid.uuid7() + chat_user_id = str(uuid.uuid7()) + chat_record_id = str(uuid.uuid7()) + TaskRecord(id=task_record_id, trigger_id=trigger_task.get('trigger'), + trigger_task_id=trigger_task.get('id'), + source_type="APPLICATION", + source_id=application_id, + task_record_id=chat_record_id, + meta={'chat_id': chat_id}, + state=State.STARTED).save() + application_parameters_setting = get_application_parameters_setting(application) + parameters = get_application_execute_parameters(parameter_setting, application_parameters_setting, kwargs) + parameters['re_chat'] = False + parameters['stream'] = True + parameters['chat_record_id'] = chat_record_id + message = parameters.get('message') + Chat.objects.get_or_create(id=chat_id, defaults={ + 'application_id': application_id, + 'abstract': message, + 'chat_user_id': chat_user_id, + 'chat_user_type': ChatUserType.ANONYMOUS_USER.value, + 'asker': {'username': "游客"}, + 'ip_address': kwargs.get('body')['ip_address'], + 'source': { + 'type': ChatSourceChoices.TRIGGER.value + }, + }) + list(ChatSerializers(data={ "chat_id": chat_id, "chat_user_id": chat_user_id, @@ -223,8 +227,22 @@ def execute(self, trigger_task, **kwargs): 'debug': False }).chat(instance=parameters)) chat_record = QuerySet(ChatRecord).filter(id=chat_record_id).first() - state = get_workflow_state(chat_record.details) - QuerySet(TaskRecord).filter(id=task_record_id).update(state=state, run_time=chat_record.run_time) + if chat_record: + state = get_workflow_state(chat_record.details) + QuerySet(TaskRecord).filter(id=task_record_id).update(state=state, run_time=chat_record.run_time, + meta={'parameter_setting': parameter_setting, + 'input': parameters, 'output': None}) + else: + QuerySet(TaskRecord).filter(id=task_record_id).update(state=State.FAILURE, + run_time=time.time() - start_time, + meta={'parameter_setting': parameter_setting, + 'input': parameters, 'output': None, + 'err_message': 'Error: An unknown error occurred during the execution of the conversation'}) except Exception as e: - state = State.FAILURE - QuerySet(TaskRecord).filter(id=task_record_id).update(state=state, run_time=0) + maxkb_logger.error(f"Application execution error: {traceback.format_exc()}") + QuerySet(TaskRecord).filter(id=task_record_id).update( + state=State.FAILURE, + run_time=time.time() - start_time, + meta={'input': {'parameter_setting': parameter_setting, **kwargs}, 'output': None, + 'err_message': 'Error: ' + str(e)} + ) diff --git a/apps/trigger/handler/impl/task/tool_task.py b/apps/trigger/handler/impl/task/tool_task.py index 338f8766d1f..a0c5e4b1810 100644 --- a/apps/trigger/handler/impl/task/tool_task.py +++ b/apps/trigger/handler/impl/task/tool_task.py @@ -184,11 +184,10 @@ def execute(self, trigger_task, **kwargs): QuerySet(TaskRecord).filter(id=task_record_id).update( state=State.FAILURE, run_time=time.time() - start_time, - meta={'input': parameter_setting, 'output': 'Error: ' + str(e)} + meta={'input': parameter_setting, 'output': 'Error: ' + str(e), 'err_message': 'Error: ' + str(e)} ) QuerySet(ToolRecord).filter(id=task_record_id).update( state=State.FAILURE, run_time=time.time() - start_time, - meta={'input': parameter_setting, 'output': 'Error: ' + str(e)} + meta={'input': parameter_setting, 'output': 'Error: ' + str(e), 'err_message': 'Error: ' + str(e)} ) - diff --git a/apps/trigger/serializers/trigger_task.py b/apps/trigger/serializers/trigger_task.py index 2c24fb15ed9..c2a9e0d091b 100644 --- a/apps/trigger/serializers/trigger_task.py +++ b/apps/trigger/serializers/trigger_task.py @@ -17,7 +17,9 @@ from common.db.search import native_page_search, get_dynamics_model from common.exception.app_exception import AppApiException from common.utils.common import get_file_content +from knowledge.models.knowledge_action import State from maxkb.conf import PROJECT_DIR +from tools.models import ToolRecord from trigger.models import TriggerTask, TaskRecord, Trigger @@ -85,10 +87,39 @@ def get_execution_details(self, is_valid=True): raise AppApiException(500, _('Trigger task record id does not exist')) if task_record.source_type == 'APPLICATION': chat_record = QuerySet(ChatRecord).filter(id=task_record.task_record_id).first() - return ChatRecordSerializerModel(chat_record).data + if chat_record: + return ChatRecordSerializerModel(chat_record).data + return { + 'state': 'TRIGGER_ERROR', + 'meta': task_record.meta + } if task_record.source_type == 'TOOL': - pass - return None + tool_record = QuerySet(ToolRecord).filter(id=task_record.task_record_id).first() + if tool_record: + return { + 'id': tool_record.id, + 'tool_id': tool_record.tool_id, + 'workspace_id': tool_record.workspace_id, + 'source_type': tool_record.source_type, + 'source_id': tool_record.source_id, + 'meta': tool_record.meta, + 'state': tool_record.state, + 'run_time': tool_record.run_time, + 'details': { + 'tool_call': { + 'index': 0, + 'result': tool_record.meta.get('output'), + 'params': tool_record.meta.get('input'), + 'status': 500 if tool_record.state == State.FAILURE else 200 if tool_record.state == State.SUCCESS else 201, + 'type': 'tool-node', + 'err_message': tool_record.meta.get('err_message') + } + } + } + return { + 'state': 'TRIGGER_ERROR', + 'meta': task_record.meta + } class TriggerTaskRecordQuerySerializer(serializers.Serializer): diff --git a/ui/src/views/trigger/component/ApplicationParameter.vue b/ui/src/views/trigger/component/ApplicationParameter.vue index ba2942b1335..9d8f02efff6 100644 --- a/ui/src/views/trigger/component/ApplicationParameter.vue +++ b/ui/src/views/trigger/component/ApplicationParameter.vue @@ -267,29 +267,36 @@ const base_field_list = computed>(() => { return result }) const init_parameters = () => { - const parameter: any = {} + const parameter: any = { ...props.modelValue } base_field_list.value.forEach((f) => { - parameter[f.field] = { source: 'custom', value: f.default_value } + if (!parameter[f.field]) { + parameter[f.field] = { source: 'custom', value: f.default_value } + } }) api_input_field_list.value.forEach((f) => { if (!parameter.api_input_field_list) { parameter['api_input_field_list'] = {} } - parameter['api_input_field_list'][f.field] = { - source: 'custom', - value: f.default_value ? f.default_value : '', + if (!parameter['api_input_field_list'][f.field]) { + parameter['api_input_field_list'][f.field] = { + source: 'custom', + value: f.default_value ? f.default_value : '', + } } }) user_input_field_list.value.forEach((f) => { if (!parameter['user_input_field_list']) { parameter['user_input_field_list'] = {} } - parameter['user_input_field_list'][f.field] = { - source: 'custom', - value: f.default_value ? f.default_value : '', + if (!parameter['user_input_field_list'][f.field]) { + parameter['user_input_field_list'][f.field] = { + source: 'custom', + value: f.default_value ? f.default_value : '', + } } }) - emit('update:modelValue', { ...parameter, ...props.modelValue }) + + emit('update:modelValue', { ...parameter }) } init_parameters() diff --git a/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue b/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue index 3651ba1f719..94d123eda8f 100644 --- a/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue +++ b/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue @@ -103,7 +103,21 @@

{{ $t('chat.executionDetails.title') }}

-