feat(scenarios): 兼容非法配置并展示错误摘要

This commit is contained in:
2026-05-30 00:36:31 +08:00
parent c57ab2f194
commit f7e0d8e4d8
4 changed files with 152 additions and 10 deletions

View File

@@ -36,15 +36,15 @@ def _get_nested(config: dict, path: tuple[str, ...]):
def validate_scenario(config: dict) -> dict:
# 校验真正影响运行闭环的必填字段;
# 页面展示字段如 applicable_questions 允许缺失,并在归一化阶段补默认值。
# 校验真正影响运行闭环的必填字段;
# 页面展示字段允许缺失,并在归一化阶段补默认值。
for field_path in REQUIRED_FIELDS:
_get_nested(config, field_path)
return normalize_scenario(config)
def normalize_scenario(config: dict) -> dict:
"""补齐页面和其模块常用的派生字段,减少模板中的条件判断。"""
"""补齐页面和其模块常用的派生字段,避免模板层重复判断。"""
normalized = dict(config)
normalized["applicable_questions"] = list(config.get("applicable_questions") or [])
normalized["rag"] = dict(config.get("rag", {}))
@@ -62,16 +62,47 @@ def _scenario_files() -> list[Path]:
return sorted([*config_dir.glob("*.yaml"), *config_dir.glob("*.yml")])
def _read_yaml_file(path: Path) -> dict:
with path.open("r", encoding="utf-8") as file:
return yaml.safe_load(file) or {}
def _collect_scenario_load_result() -> tuple[list[dict], list[dict]]:
"""
统一读取配置目录中的所有场景文件。
返回值:
- scenarios: 校验通过的场景列表
- issues: 非法 YAML / 缺字段等错误摘要,供首页展示
"""
scenarios = []
issues = []
for path in _scenario_files():
try:
config = _read_yaml_file(path)
scenarios.append(validate_scenario(config))
except (yaml.YAMLError, ScenarioValidationError) as exc:
issues.append(
{
"file_name": path.name,
"message": str(exc),
}
)
return scenarios, issues
def list_scenarios() -> list[dict]:
# 首页每次读取最新 YAML便于复试现场快速改题。
scenarios = []
for path in _scenario_files():
with path.open("r", encoding="utf-8") as file:
config = yaml.safe_load(file) or {}
scenarios.append(validate_scenario(config))
scenarios, _issues = _collect_scenario_load_result()
return scenarios
def list_scenario_issues() -> list[dict]:
"""返回配置异常摘要,便于页面明确提示而不是直接 500。"""
_scenarios, issues = _collect_scenario_load_result()
return issues
def get_scenario(scenario_id: str) -> dict:
for scenario in list_scenarios():
if scenario["id"] == scenario_id: