diff --git a/apps/application/flow/compare/__init__.py b/apps/application/flow/compare/__init__.py index ce0c430e1ad..532922f25ed 100644 --- a/apps/application/flow/compare/__init__.py +++ b/apps/application/flow/compare/__init__.py @@ -62,9 +62,10 @@ def _compare(source_value, compare, target_value): return compare_handler.compare(source_value, compare, target_value) -def _assertion(workflow_manage, field_list: List[str], compare: str, value): +def _assertion(workflow_manage, field_list: List[str], compare: str, target_value, condition_details: list = None): + origin_target_value = target_value try: - value = workflow_manage.generate_prompt(value) + target_value = workflow_manage.generate_prompt(target_value) except Exception: pass field_value = None @@ -72,12 +73,28 @@ def _assertion(workflow_manage, field_list: List[str], compare: str, value): field_value = workflow_manage.get_reference_field(field_list[0], field_list[1:]) except Exception: pass - return _compare(field_value, compare, value) + result = _compare(field_value, compare, target_value) -def do_assertion(workflow_manage, condition, condition_list): + # condition_details不为None,说明调用端需要分支执行详情,拼接到列表中 + if condition_details is not None: + condition_details.append({ + 'field': field_list, + 'field_type': type(field_value).__name__ if field_value is not None else None, + 'field_value': field_value, + 'compare': compare, + 'target_type': type(target_value).__name__ if target_value is not None else None, + 'target_value': target_value, + 'origin_target_value': origin_target_value if origin_target_value != target_value else '', + 'result': result + }) + + return result + + +def do_assertion(workflow_manage, condition, condition_list, condition_details: list = None): b = False if condition == 'and' else True for row in condition_list: - if _assertion(workflow_manage, row.get('field'), row.get('compare'), row.get('value')) is b: + if _assertion(workflow_manage, row.get('field'), row.get('compare'), row.get('value'), condition_details) is b: return b return not b diff --git a/apps/application/flow/step_node/condition_node/impl/base_condition_node.py b/apps/application/flow/step_node/condition_node/impl/base_condition_node.py index e0da03ace4c..d776ece53f4 100644 --- a/apps/application/flow/step_node/condition_node/impl/base_condition_node.py +++ b/apps/application/flow/step_node/condition_node/impl/base_condition_node.py @@ -17,21 +17,38 @@ class BaseConditionNode(IConditionNode): def save_context(self, details, workflow_manage): self.context['branch_id'] = details.get('branch_id') self.context['branch_name'] = details.get('branch_name') + self.context['branch_details'] = details.get('branch_details') self.context['exception_message'] = details.get('err_message') def execute(self, **kwargs) -> NodeResult: branch_list = self.node_params_serializer.data['branch'] - branch = self._execute(branch_list) - r = NodeResult({'branch_id': branch.get('id'), 'branch_name': branch.get('type')}, {}) + branch, branch_details = self._execute(branch_list) + r = NodeResult({ + 'branch_id': branch.get('id') if branch else None, + 'branch_name': branch.get('type') if branch else None, + 'branch_details': branch_details + }, {}) return r def _execute(self, branch_list: List): + branch_details = [] for branch in branch_list: - if self.branch_assertion(branch): - return branch + is_matched, condition_details = self.branch_assertion(branch) + branch_details.append({ + 'id': branch.get('id'), + 'type': branch.get('type'), + 'condition_logic': branch.get('condition'), + 'is_matched': is_matched, + 'conditions': condition_details + }) + if is_matched: + return branch, branch_details + return None, branch_details def branch_assertion(self, branch): - return do_assertion(self.workflow_manage, branch.get('condition'), branch.get('conditions')) + condition_details = [] + is_matched = do_assertion(self.workflow_manage, branch.get('condition'), branch.get('conditions'), condition_details) + return is_matched, condition_details def get_details(self, index: int, **kwargs): return { @@ -40,6 +57,7 @@ def get_details(self, index: int, **kwargs): 'run_time': self.context.get('run_time'), 'branch_id': self.context.get('branch_id'), 'branch_name': self.context.get('branch_name'), + 'branch_details': self.context.get('branch_details'), 'type': self.node.type, 'status': self.status, 'err_message': self.err_message, diff --git a/ui/src/components/execution-detail-card/index.vue b/ui/src/components/execution-detail-card/index.vue index f163b40c7a3..821b680a42d 100644 --- a/ui/src/components/execution-detail-card/index.vue +++ b/ui/src/components/execution-detail-card/index.vue @@ -177,12 +177,50 @@ @@ -1400,6 +1438,7 @@ import { ref, computed, type PropType } from 'vue' import ParagraphCard from '@/components/ai-chat/component/knowledge-source-component/ParagraphCard.vue' import DynamicsForm from '@/components/dynamics-form/index.vue' +import { compareList } from '@/workflow/common/data' import { iconComponent } from '@/workflow/icons/utils' import { WorkflowType } from '@/enums/application' import { getImgUrl } from '@/utils/common' @@ -1422,6 +1461,36 @@ const isKnowLedge = computed(() => props.type === 'knowledge') const currentLoopNode = ref(0) const currentParagraph = ref(0) const currentWriteContent = ref(0) + +// 格式化值显示 +const formatValue = (value: any, value_type: any): string => { + if (value === null || value === undefined) { + return 'null' + } + if (value === '') { + return `${value_type}: ""` + } + if (typeof value === 'string') { + return `${value_type}: "${value}"` + } + if (Array.isArray(value)) { + return `${value_type}: ${JSON.stringify(value)}` + } + if (typeof value === 'object') { + return `${value_type}: ${JSON.stringify(value)}` + } + return `${value_type}: ${value}` +} + +const compareMap: Record = compareList.reduce((acc, cur) => { + acc[cur.value] = cur.label + return acc +}, {} as Record) + +// 获取比较操作符标签 +const getCompareLabel = (compare: string): string => { + return compareMap[compare] || compare +} diff --git a/ui/src/locales/lang/en-US/ai-chat.ts b/ui/src/locales/lang/en-US/ai-chat.ts index cffe1baaaf3..2a8ae6759d0 100644 --- a/ui/src/locales/lang/en-US/ai-chat.ts +++ b/ui/src/locales/lang/en-US/ai-chat.ts @@ -109,6 +109,7 @@ export default { searchContent: 'Search Query', searchResult: 'Search Results', conditionResult: 'Condition Evaluation', + branchEvaluationDetails: 'Branch Evaluation Details', currentChat: 'Current Chat', answer: 'AI Response', replyContent: 'Reply Content', diff --git a/ui/src/locales/lang/zh-CN/ai-chat.ts b/ui/src/locales/lang/zh-CN/ai-chat.ts index afa0a32a900..eada4351b22 100644 --- a/ui/src/locales/lang/zh-CN/ai-chat.ts +++ b/ui/src/locales/lang/zh-CN/ai-chat.ts @@ -107,6 +107,7 @@ export default { searchContent: '检索内容', searchResult: '检索结果', conditionResult: '判断结果', + branchEvaluationDetails: '分支判断详情', currentChat: '本次对话', answer: 'AI 回答', replyContent: '回复内容', diff --git a/ui/src/locales/lang/zh-Hant/ai-chat.ts b/ui/src/locales/lang/zh-Hant/ai-chat.ts index 9731cf2f238..18239125ac9 100644 --- a/ui/src/locales/lang/zh-Hant/ai-chat.ts +++ b/ui/src/locales/lang/zh-Hant/ai-chat.ts @@ -107,6 +107,7 @@ export default { searchContent: '檢索內容', searchResult: '檢索結果', conditionResult: '判斷結果', + branchEvaluationDetails: '分支判斷詳情', currentChat: '本次對話', answer: 'AI 回答', replyContent: '回覆內容',