Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 60 additions & 42 deletions apps/trigger/handler/impl/task/application_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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'):
Expand All @@ -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'):
Expand Down Expand Up @@ -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'): {
Expand Down Expand Up @@ -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,
Expand All @@ -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)}
)
5 changes: 2 additions & 3 deletions apps/trigger/handler/impl/task/tool_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)}
)

37 changes: 34 additions & 3 deletions apps/trigger/serializers/trigger_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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):
Expand Down
25 changes: 16 additions & 9 deletions ui/src/views/trigger/component/ApplicationParameter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -267,29 +267,36 @@ const base_field_list = computed<Array<any>>(() => {
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()
Expand Down
23 changes: 20 additions & 3 deletions ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,21 @@
<h4 class="title-decoration-1 mb-16 mt-4">
{{ $t('chat.executionDetails.title') }}
</h4>
<template v-for="(item, index) in arraySort(detail ?? [], 'index')" :key="index">
<template v-if="taskRecordDetails && taskRecordDetails.state === 'TRIGGER_ERROR'">
<div class="card-never border-r-6 mb-12">
<h5 class="p-8-12">触发器入参</h5>
<div class="p-8-12 border-t-dashed lighter">
{{ taskRecordDetails.meta.input }}
</div>
</div>
<div class="card-never border-r-6 mb-12">
<h5 class="p-8-12">错误信息</h5>
<div class="p-8-12 border-t-dashed lighter">
{{ taskRecordDetails.meta.err_message }}
</div>
</div>
</template>
<template v-else v-for="(item, index) in arraySort(detail ?? [], 'index')" :key="index">
<ExecutionDetailCard :data="item"> </ExecutionDetailCard>
</template>
</el-scrollbar>
Expand Down Expand Up @@ -165,7 +179,7 @@ const apiType = computed(() => {
return 'workspace'
}
})

const taskRecordDetails = ref<any>()
const detail = ref<any>(null)

const loading = ref(false)
Expand Down Expand Up @@ -197,7 +211,10 @@ function getDetail() {
props.currentContent?.id,
)
.then((ok) => {
detail.value = Object.values(ok.data.details)
if (ok.data.details) {
detail.value = Object.values(ok.data.details)
}
taskRecordDetails.value = ok.data
})
}

Expand Down