Skip to content
Closed
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
8 changes: 6 additions & 2 deletions apps/application/flow/compare/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@
from .not_equal_compare import NotEqualCompare
from .regex_compare import RegexCompare
from .start_with import StartWithCompare
from .type_is_compare import TypeIsCompare
from .type_not_compare import TypeNotCompare
from .wildcard_compare import WildcardCompare

_compare_handler_dict = {
'is_null': IsNullCompare(),
'is_not_null': IsNotNullCompare(),
'contain': ContainCompare(),
'not_contain': NotContainCompare(),
'regex': RegexCompare(),
'wildcard': WildcardCompare(),
'eq': EqualCompare(),
'not_eq': NotEqualCompare(),
'ge': GECompare(),
Expand All @@ -48,10 +52,10 @@
'len_lt': LenLTCompare(),
'is_true': IsTrueCompare(),
'is_not_true': IsNotTrueCompare(),
'type_is': TypeIsCompare(),
'type_not': TypeNotCompare(),
'start_with': StartWithCompare(),
'end_with': EndWithCompare(),
'regex': RegexCompare(),
'wildcard': WildcardCompare(),
}


Expand Down
23 changes: 23 additions & 0 deletions apps/application/flow/compare/type_is_compare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# coding=utf-8
"""
@project: MaxKB
@Author:wangliang181230
@file:type_is_compare.py
@date:2026/5/25 10:01
@desc: “数据类型是” 比较器
"""
from .compare import Compare


class TypeIsCompare(Compare):

def compare(self, source_value, compare, target_value):
try:
if target_value == "json":
return isinstance(source_value, (list, dict))
elif target_value == "num":
return isinstance(source_value, (int, float))
else:
return type(source_value).__name__ == target_value
except Exception:
return False
23 changes: 23 additions & 0 deletions apps/application/flow/compare/type_not_compare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# coding=utf-8
"""
@project: MaxKB
@Author:wangliang181230
@file:type_not_compare.py
@date:2026/5/25 10:01
@desc: “数据类型不是” 比较器
"""
from .compare import Compare


class TypeNotCompare(Compare):

def compare(self, source_value, compare, target_value):
try:
if target_value == "json":
return not isinstance(source_value, (list, dict))
elif target_value == "num":
return not isinstance(source_value, (int, float))
else:
return type(source_value).__name__ != target_value
except Exception:
return False
9 changes: 7 additions & 2 deletions ui/src/locales/lang/en-US/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ You are a master of problem optimization, adept at accurately inferring user int
requiredMessage: 'Please select conditions',
},
valueMessage: 'Please enter a value',
verify_type_compare: {
requiredMessage: 'Please select a type',
},
addCondition: 'Add Condition',
addBranch: 'Add Branch',
},
Expand Down Expand Up @@ -537,6 +540,8 @@ You are a master of problem optimization, adept at accurately inferring user int
is_not_null: 'Is not null',
contain: 'Contains',
not_contain: 'Does not contain',
regex: 'Regex matching',
wildcard: 'Wildcard matching',
eq: 'Equal to',
not_eq: 'Not equal to',
ge: 'Greater than or equal to',
Expand All @@ -550,8 +555,8 @@ You are a master of problem optimization, adept at accurately inferring user int
len_lt: 'Length less than',
is_true: 'Is true',
is_not_true: 'Is not true',
regex: 'Regex matching',
wildcard: 'Wildcard matching',
type_is: 'Type is',
type_not: 'Type not',
},
SystemPromptPlaceholder: 'System Prompt, can reference variables in the system, such as',
UserPromptPlaceholder: 'User Prompt, can reference variables in the system, such as',
Expand Down
9 changes: 7 additions & 2 deletions ui/src/locales/lang/zh-CN/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ export default {
requiredMessage: '请选择条件',
},
valueMessage: '请输入值',
verify_type_compare: {
requiredMessage: '请选择类型',
},
addCondition: '添加条件',
addBranch: '添加分支',
},
Expand Down Expand Up @@ -528,6 +531,8 @@ export default {
is_not_null: '不为空',
contain: '包含',
not_contain: '不包含',
regex: '正则匹配',
wildcard: '通配符匹配',
eq: '等于',
not_eq: '不等于',
ge: '大于等于',
Expand All @@ -541,8 +546,8 @@ export default {
len_lt: '长度小于',
is_true: '为真',
is_not_true: '不为真',
regex: '正则匹配',
wildcard: '通配符匹配',
type_is: '类型是',
type_not: '类型不是',
},
SystemPromptPlaceholder: '系统提示词,可以引用系统中的变量:如',
UserPromptPlaceholder: '用户提示词,可以引用系统中的变量:如',
Expand Down
9 changes: 7 additions & 2 deletions ui/src/locales/lang/zh-Hant/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ export default {
requiredMessage: '請選擇條件',
},
valueMessage: '請輸入值',
verify_type_compare: {
requiredMessage: '請選擇類型',
},
addCondition: '添加條件',
addBranch: '添加分支',
},
Expand Down Expand Up @@ -522,6 +525,8 @@ export default {
is_not_null: '不為空',
contain: '包含',
not_contain: '不包含',
regex: '正則匹配',
wildcard: '通配符匹配',
eq: '等於',
not_eq: '不等於',
ge: '大於等於',
Expand All @@ -535,8 +540,8 @@ export default {
len_lt: '長度小於',
is_true: '為真',
is_not_true: '不為真',
regex: '正則匹配',
wildcard: '通配符匹配',
type_is: '類型是',
type_not: '類型不是',
},
SystemPromptPlaceholder: '系統提示詞,可以引用系統中的變量:如',
UserPromptPlaceholder: '用戶提示詞,可以引用系統中的變量:如',
Expand Down
12 changes: 8 additions & 4 deletions ui/src/workflow/common/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,8 @@ export const compareList = [
{ value: 'is_not_null', label: t('workflow.compare.is_not_null') },
{ value: 'contain', label: t('workflow.compare.contain') },
{ value: 'not_contain', label: t('workflow.compare.not_contain') },
{ value: 'regex', label: t('workflow.compare.regex') },
{ value: 'wildcard', label: t('workflow.compare.wildcard') },
{ value: 'eq', label: t('workflow.compare.eq') },
{ value: 'not_eq', label: t('workflow.compare.not_eq') },
{ value: 'ge', label: t('workflow.compare.ge') },
Expand All @@ -1138,10 +1140,10 @@ export const compareList = [
{ value: 'len_lt', label: t('workflow.compare.len_lt') },
{ value: 'is_true', label: t('workflow.compare.is_true') },
{ value: 'is_not_true', label: t('workflow.compare.is_not_true') },
{ value: 'type_is', label: t('workflow.compare.type_is') },
{ value: 'type_not', label: t('workflow.compare.type_not') },
{ value: 'start_with', label: 'startWith' },
{ value: 'end_with', label: 'endWith' },
{ value: 'regex', label: t('workflow.compare.regex') },
{ value: 'wildcard', label: t('workflow.compare.wildcard') },
]
export const nodeDict: any = {
[WorkflowType.AiChat]: aiChatNode,
Expand Down Expand Up @@ -1533,6 +1535,8 @@ ${t('workflow.nodes.formNode.form_content_format2')}`,
'workflow.compare.is_not_null',
'workflow.compare.contain',
'workflow.compare.not_contain',
'workflow.compare.regex',
'workflow.compare.wildcard',
'workflow.compare.eq',
'workflow.compare.not_eq',
'workflow.compare.ge',
Expand All @@ -1546,9 +1550,9 @@ ${t('workflow.nodes.formNode.form_content_format2')}`,
'workflow.compare.len_lt',
'workflow.compare.is_true',
'workflow.compare.is_not_true',
'workflow.compare.type_is',
'workflow.compare.type_not',
].forEach((key, index) => defineLocaleGetter(compareList[index], 'label', key))
defineLocaleGetter(compareList[19], 'label', 'workflow.compare.regex')
defineLocaleGetter(compareList[20], 'label', 'workflow.compare.wildcard')

export function isWorkFlow(type: string | undefined) {
return type === 'WORK_FLOW'
Expand Down
20 changes: 17 additions & 3 deletions ui/src/workflow/nodes/condition-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,25 @@
trigger: 'blur',
}"
>
<el-select
v-if="['type_is', 'type_not'].includes(condition.compare)"
v-model="condition.value"
:placeholder="$t('workflow.nodes.conditionNode.verify_type_compare.requiredMessage')"
>
<el-option label="json" value="json" />
<el-option label="dict" value="dict" />
<el-option label="array" value="list" />
<el-option label="string" value="str" />
<el-option label="num" value="num" />
<el-option label="int" value="int" />
<el-option label="float" value="float" />
<el-option label="boolean" value="bool" />
<el-option label="null" value="NoneType" />
</el-select>
<el-input
v-else
v-model="condition.value"
:placeholder="
$t('workflow.nodes.conditionNode.valueMessage')
"
:placeholder="$t('workflow.nodes.conditionNode.valueMessage')"
/>
</el-form-item>
</el-col>
Expand Down
16 changes: 16 additions & 0 deletions ui/src/workflow/nodes/loop-break-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,23 @@
trigger: 'blur',
}"
>
<el-select
v-if="['type_is', 'type_not'].includes(condition.compare)"
v-model="condition.value"
:placeholder="$t('workflow.nodes.conditionNode.verify_type_compare.requiredMessage')"
>
<el-option label="json" value="json" />
<el-option label="dict" value="dict" />
<el-option label="array" value="list" />
<el-option label="string" value="str" />
<el-option label="num" value="num" />
<el-option label="int" value="int" />
<el-option label="float" value="float" />
<el-option label="boolean" value="bool" />
<el-option label="null" value="NoneType" />
</el-select>
<el-input
v-else
v-model="condition.value"
:placeholder="$t('workflow.nodes.conditionNode.valueMessage')"
/>
Expand Down
16 changes: 16 additions & 0 deletions ui/src/workflow/nodes/loop-continue-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,23 @@
trigger: 'blur',
}"
>
<el-select
v-if="['type_is', 'type_not'].includes(condition.compare)"
v-model="condition.value"
:placeholder="$t('workflow.nodes.conditionNode.verify_type_compare.requiredMessage')"
>
<el-option label="json" value="json" />
<el-option label="dict" value="dict" />
<el-option label="array" value="list" />
<el-option label="string" value="str" />
<el-option label="num" value="num" />
<el-option label="int" value="int" />
<el-option label="float" value="float" />
<el-option label="boolean" value="bool" />
<el-option label="null" value="NoneType" />
</el-select>
<el-input
v-else
v-model="condition.value"
:placeholder="$t('workflow.nodes.conditionNode.valueMessage')"
/>
Expand Down
Loading