Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,80 @@
from typing import List

from application.flow.i_step_node import NodeResult
from application.flow.compare import do_assertion
from application.flow.compare import _assertion
from application.flow.step_node.condition_node.i_condition_node import IConditionNode


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
condition_details = self._evaluate_conditions(branch)
is_matched = all(cond.get('result', False) for cond in condition_details) if branch.get('condition') == 'and' else any(cond.get('result', False) for cond in condition_details)

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'))
def _evaluate_conditions(self, branch):
condition_logic = branch.get('condition')
condition_list = branch.get('conditions', [])
condition_details = []

for condition in condition_list:
field_list = condition.get('field', [])
compare = condition.get('compare', '')
value = condition.get('value', '')

try:
field_value = self.workflow_manage.get_reference_field(field_list[0], field_list[1:])
except Exception:
field_value = None

try:
evaluated_value = self.workflow_manage.generate_prompt(value)
except Exception:
evaluated_value = value

result = _assertion(self.workflow_manage, field_list, compare, value)

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(evaluated_value).__name__ if evaluated_value is not None else None,
'target_value': evaluated_value,
'result': result
})

if (condition_logic == "and" and not result) or (condition_logic == 'or' and result):
break

return condition_details

def get_details(self, index: int, **kwargs):
return {
Expand All @@ -40,6 +91,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,
Expand Down
86 changes: 85 additions & 1 deletion ui/src/components/execution-detail-card/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,43 @@
{{ $t('aiChat.executionDetails.conditionResult') }}
</h5>
<div class="p-8-12 border-t-dashed lighter">
{{ data.branch_name || '-' }}
<el-tag type="success" size="small">
{{ data.branch_name || '-' }}
</el-tag>
</div>
</div>
<!-- 判断器执行细节 -->
<div class="card-never border-r-6 mt-8" v-if="data.branch_details && data.branch_details.length > 0" v-for="(branch, bIndex) in data.branch_details" :key="bIndex">
<h5 class="p-8-12">
<span class="min-w-25">
<el-tag :type="branch.is_matched ? 'success' : 'error'" size="small">
{{ branch.type || '-' }}
</el-tag>
<span class="ml-4">{{ $t('aiChat.executionDetails.branchEvaluationDetails') }}</span>
</span>
<span class="min-w-25" v-if="branch.type !== 'ELSE'">
<span class="color-secondary">{{ $t('aiChat.executionDetails.conditionLogic') }}:</span>
<el-tag type="warning" size="small" class="ml-4">
{{ branch.condition_logic === 'and' ? $t('aiChat.executionDetails.and') : $t('aiChat.executionDetails.or') }}
</el-tag>
</span>
</h5>
<div class="border-t-dashed lighter clean" style="padding: 0 12px 8px 12px">
<div v-if="branch.conditions && branch.conditions.length > 0" v-for="(cond, cIndex) in branch.conditions" :key="cIndex" class="mt-8">
<el-tag type="warn" size="small" class="f_val" :title="formatValue(cond.field_value, cond.field_type)">
{{ formatValue(cond.field_value, cond.field_type) }}
</el-tag>
<el-tag type="primary" size="small" class="ml-8">{{ getCompareLabel(cond.compare) }}</el-tag>
<el-tag type="warn" size="small" class="f_val"
v-if="!['is_null', 'is_not_null', 'is_true', 'is_not_true', 'is_false', 'is_not_false'].includes(cond.compare)"
>
{{ formatValue(cond.target_value, cond.target_type) }}
</el-tag>
<span class="ml-8">=</span>
<el-tag :type="cond.result ? 'success' : 'danger'" size="small" class="ml-8">
{{ cond.result ? 'True' : 'False' }}
</el-tag>
</div>
</div>
</div>
</template>
Expand Down Expand Up @@ -1400,6 +1436,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'
Expand All @@ -1422,11 +1459,58 @@ 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<string, string> = compareList.reduce((acc, cur) => {
acc[cur.value] = cur.label
return acc
}, {} as Record<string, string>)

// 获取比较操作符标签
const getCompareLabel = (compare: string): string => {
return compareMap[compare] || compare
}
</script>
<style lang="scss" scoped>
.execution-detail-card {
:deep(.md-editor-previewOnly) {
background: none !important;
}
}

.min-w-25 {
min-width: 25%;
max-width: 33.33%;
display: inline-block;
}

.f_val {
margin-left: 4px;
max-width: 30%;

* {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
</style>
4 changes: 4 additions & 0 deletions ui/src/locales/lang/en-US/ai-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ export default {
searchContent: 'Search Query',
searchResult: 'Search Results',
conditionResult: 'Condition Evaluation',
branchEvaluationDetails: 'Branch Evaluation Details',
conditionLogic: 'Condition Logic',
and: 'AND',
or: 'OR',
currentChat: 'Current Chat',
answer: 'AI Response',
replyContent: 'Reply Content',
Expand Down
4 changes: 4 additions & 0 deletions ui/src/locales/lang/zh-CN/ai-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ export default {
searchContent: '检索内容',
searchResult: '检索结果',
conditionResult: '判断结果',
branchEvaluationDetails: '分支判断详情',
conditionLogic: '条件逻辑',
and: '所有(AND)',
or: '任一(OR)',
currentChat: '本次对话',
answer: 'AI 回答',
replyContent: '回复内容',
Expand Down
4 changes: 4 additions & 0 deletions ui/src/locales/lang/zh-Hant/ai-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ export default {
searchContent: '檢索內容',
searchResult: '檢索結果',
conditionResult: '判斷結果',
branchEvaluationDetails: '分支判斷詳情',
conditionLogic: '條件邏輯',
and: '所有(AND)',
or: '任一(OR)',
currentChat: '本次對話',
answer: 'AI 回答',
replyContent: '回覆內容',
Expand Down
Loading