feat(scenarios): 增强场景摘要与题型展示
This commit is contained in:
@@ -36,9 +36,23 @@ def _get_nested(config: dict, path: tuple[str, ...]):
|
|||||||
|
|
||||||
|
|
||||||
def validate_scenario(config: dict) -> dict:
|
def validate_scenario(config: dict) -> dict:
|
||||||
|
# 只校验真正影响运行闭环的必填字段;
|
||||||
|
# 页面展示类字段如 applicable_questions 允许缺失,并在归一化阶段补默认值。
|
||||||
for field_path in REQUIRED_FIELDS:
|
for field_path in REQUIRED_FIELDS:
|
||||||
_get_nested(config, field_path)
|
_get_nested(config, field_path)
|
||||||
return config
|
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", {}))
|
||||||
|
normalized["rag"]["enabled"] = bool(normalized["rag"].get("enabled"))
|
||||||
|
normalized["tools"] = list(config.get("tools") or [])
|
||||||
|
normalized["tool_count"] = len(normalized["tools"])
|
||||||
|
normalized["is_enabled"] = True
|
||||||
|
return normalized
|
||||||
|
|
||||||
|
|
||||||
def _scenario_files() -> list[Path]:
|
def _scenario_files() -> list[Path]:
|
||||||
@@ -49,6 +63,7 @@ def _scenario_files() -> list[Path]:
|
|||||||
|
|
||||||
|
|
||||||
def list_scenarios() -> list[dict]:
|
def list_scenarios() -> list[dict]:
|
||||||
|
# 首页每次读取最新 YAML,便于复试现场快速改题。
|
||||||
scenarios = []
|
scenarios = []
|
||||||
for path in _scenario_files():
|
for path in _scenario_files():
|
||||||
with path.open("r", encoding="utf-8") as file:
|
with path.open("r", encoding="utf-8") as file:
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ from .services import list_scenarios
|
|||||||
|
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
|
# 首页只消费服务层给出的场景摘要,不自行拼装配置字段。
|
||||||
return render(request, "scenarios/index.html", {"scenarios": list_scenarios()})
|
return render(request, "scenarios/index.html", {"scenarios": list_scenarios()})
|
||||||
|
|||||||
@@ -17,8 +17,16 @@
|
|||||||
<ul class="meta-list">
|
<ul class="meta-list">
|
||||||
<li class="meta-badge">场景 ID:{{ scenario.id }}</li>
|
<li class="meta-badge">场景 ID:{{ scenario.id }}</li>
|
||||||
<li class="meta-badge">输出:{{ scenario.output.type }}</li>
|
<li class="meta-badge">输出:{{ scenario.output.type }}</li>
|
||||||
<li class="meta-badge">工具数:{{ scenario.tools|length }}</li>
|
<li class="meta-badge">RAG:{% if scenario.rag.enabled %}已启用{% else %}未启用{% endif %}</li>
|
||||||
|
<li class="meta-badge">工具数:{{ scenario.tool_count }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<p class="muted" style="margin-top: 14px;">适用题型:
|
||||||
|
{% if scenario.applicable_questions %}
|
||||||
|
{{ scenario.applicable_questions|join:"、" }}
|
||||||
|
{% else %}
|
||||||
|
暂未配置
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
<p style="margin-top: 16px;">
|
<p style="margin-top: 16px;">
|
||||||
<a class="button button-primary" href="{% url 'chat:index' scenario.id %}">进入对话</a>
|
<a class="button button-primary" href="{% url 'chat:index' scenario.id %}">进入对话</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -23,8 +23,18 @@ def test_get_scenario_returns_full_agent_config():
|
|||||||
assert scenario["agent"]["role"] == "质量管理专家"
|
assert scenario["agent"]["role"] == "质量管理专家"
|
||||||
assert scenario["rag"]["enabled"] is True
|
assert scenario["rag"]["enabled"] is True
|
||||||
assert scenario["output"]["type"] == "quality_report"
|
assert scenario["output"]["type"] == "quality_report"
|
||||||
|
assert "质量异常分析" in scenario["applicable_questions"][0]
|
||||||
|
|
||||||
|
|
||||||
def test_get_scenario_raises_clear_error_for_missing_id():
|
def test_get_scenario_raises_clear_error_for_missing_id():
|
||||||
with pytest.raises(ScenarioNotFound, match="场景不存在"):
|
with pytest.raises(ScenarioNotFound, match="场景不存在"):
|
||||||
get_scenario("missing")
|
get_scenario("missing")
|
||||||
|
|
||||||
|
|
||||||
|
def test_home_page_shows_applicable_questions(client):
|
||||||
|
response = client.get("/")
|
||||||
|
|
||||||
|
content = response.content.decode("utf-8")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert "适用题型" in content
|
||||||
|
assert "SOP 问答" in content
|
||||||
|
|||||||
Reference in New Issue
Block a user