feat: restore source parity and harden agent runtime

This commit is contained in:
2026-06-22 11:17:26 +08:00
parent e33f08277b
commit 0793eb82d6
596 changed files with 168879 additions and 290 deletions
@@ -0,0 +1,218 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
条件表达式求值器
负责解析和执行条件分支的表达式
"""
import logging
import operator
from decimal import Decimal
from typing import Any, Dict, List, Optional
logger = logging.getLogger(__name__)
class ConditionEvaluator:
"""
条件求值器
支持的操作符:
- eq: 等于
- ne: 不等于
- gt: 大于
- gte: 大于等于
- lt: 小于
- lte: 小于等于
- contains: 包含
- not_contains: 不包含
- in: 在...中
- not_in: 不在...中
- empty: 为空
- not_empty: 不为空
"""
# 操作符映射
OPERATORS = {
'eq': operator.eq,
'ne': operator.ne,
'gt': operator.gt,
'gte': operator.ge,
'lt': operator.lt,
'lte': operator.le,
}
def evaluate_groups(self, groups: List[Dict], form_data: Dict) -> bool:
"""
求值条件组列表(组之间是 OR 关系)
Args:
groups: 条件组列表,每个组包含 conditions 数组
form_data: 表单数据
Returns:
bool: 任一组满足则返回 True
"""
if not groups:
return True
for group in groups:
if self.evaluate_group(group, form_data):
return True
return False
def evaluate_group(self, group: Dict, form_data: Dict) -> bool:
"""
求值单个条件组(组内条件是 AND 关系)
Args:
group: 条件组,包含 conditions 数组
form_data: 表单数据
Returns:
bool: 所有条件都满足才返回 True
"""
conditions = group.get('conditions', [])
if not conditions:
return True
for condition in conditions:
if not self.evaluate_condition(condition, form_data):
return False
return True
def evaluate_condition(self, condition: Dict, form_data: Dict) -> bool:
"""
求值单个条件
Args:
condition: 条件定义 {field, operator, value}
form_data: 表单数据
Returns:
bool: 条件是否满足
"""
field = condition.get('field', '')
op = condition.get('operator', 'eq')
expected_value = condition.get('value')
actual_value = self._get_field_value(form_data, field)
logger.info(
f"条件求值: field={field}, operator={op}, "
f"expected={expected_value!r}(type={type(expected_value).__name__}), "
f"actual={actual_value!r}(type={type(actual_value).__name__})"
)
try:
result = self._compare(actual_value, op, expected_value)
logger.info(f"条件求值结果: {result}")
return result
except Exception as e:
logger.warning(f"条件求值失败: {condition}, 错误: {e}")
return False
def _get_field_value(self, data: Dict, field: str) -> Any:
"""
获取字段值,支持嵌套路径(如 user.dept.name
"""
if not field:
return None
parts = field.split('.')
value = data
for part in parts:
if isinstance(value, dict):
value = value.get(part)
else:
return None
return value
def _compare(self, actual: Any, op: str, expected: Any) -> bool:
"""
执行比较操作
"""
# 空值检查
if op == 'empty':
return self._is_empty(actual)
if op == 'not_empty':
return not self._is_empty(actual)
# 包含检查
if op == 'contains':
return self._contains(actual, expected)
if op == 'not_contains':
return not self._contains(actual, expected)
# 集合检查
if op == 'in':
return self._in_list(actual, expected)
if op == 'not_in':
return not self._in_list(actual, expected)
# 数值比较(需要类型转换)
if op in ('gt', 'gte', 'lt', 'lte'):
actual = self._to_number(actual)
expected = self._to_number(expected)
if actual is None or expected is None:
return False
# 等于/不等于:先尝试原始比较,如果类型不同则统一转字符串再比较
if op in ('eq', 'ne'):
if type(actual) != type(expected) and actual is not None and expected is not None:
result = self.OPERATORS[op](str(actual).strip(), str(expected).strip())
logger.debug(f"类型不一致,转字符串比较: {str(actual)!r} {op} {str(expected)!r} = {result}")
return result
return self.OPERATORS[op](actual, expected)
# 其他标准比较
if op in self.OPERATORS:
return self.OPERATORS[op](actual, expected)
return actual == expected
def _is_empty(self, value: Any) -> bool:
"""检查值是否为空"""
if value is None:
return True
if isinstance(value, str) and value.strip() == '':
return True
if isinstance(value, (list, dict)) and len(value) == 0:
return True
return False
def _contains(self, actual: Any, expected: Any) -> bool:
"""检查是否包含"""
if actual is None:
return False
if isinstance(actual, str):
return str(expected) in actual
if isinstance(actual, (list, tuple)):
return expected in actual
return False
def _in_list(self, actual: Any, expected: Any) -> bool:
"""检查是否在列表中"""
if not isinstance(expected, (list, tuple)):
expected = [expected]
return actual in expected
def _to_number(self, value: Any) -> Optional[float]:
"""转换为数字"""
if value is None:
return None
if isinstance(value, (int, float, Decimal)):
return float(value)
if isinstance(value, str):
try:
return float(value)
except ValueError:
return None
return None
# 全局实例
condition_evaluator = ConditionEvaluator()