feat: make mode creation preview-only and cache-safe

This commit is contained in:
Miayui
2026-09-20 19:32:03 +08:00
parent bfff1b515c
commit 89707a42e2
28 changed files with 1375 additions and 165 deletions
+128 -3
View File
@@ -11,6 +11,8 @@ from cognitive_agent.application.assistant_capabilities import AssistantCapabili
from cognitive_agent.application.scene_composer import (
build_scene_output_schema,
normalize_scene_output,
scene_has_explicit_control_object,
scene_required_native_fallbacks,
scene_required_peripheral_refs,
scene_semantic_guidance,
)
@@ -464,7 +466,7 @@ def test_learning_mode_is_grounded_as_free_semantic_composition() -> None:
@pytest.mark.parametrize("mode_name", ("浪漫模式", "中秋欢快模式"))
def test_romantic_and_mid_autumn_require_flashing_light_actions(
def test_romantic_and_mid_autumn_require_decorative_light_actions(
mode_name: str,
) -> None:
context = _context()
@@ -490,6 +492,27 @@ def test_romantic_and_mid_autumn_require_flashing_light_actions(
"action_label": "关闭",
"action_names": ["关闭", "熄灭"],
},
{
"ref": "ir:strip-open",
"device_label": "灯带",
"object_names": ["灯带", "LED 灯条"],
"action_label": "打开",
"action_names": ["打开", "开启"],
},
{
"ref": "ir:strip-red",
"device_label": "灯带",
"object_names": ["灯带", "LED 灯条"],
"action_label": "切换为红色",
"action_names": ["切换为红色", "设置为红色"],
},
{
"ref": "ir:ambient-open",
"device_label": "外设氛围灯",
"object_names": ["外设氛围灯", "氛围灯"],
"action_label": "打开",
"action_names": ["打开", "开启"],
},
]
required = scene_required_peripheral_refs(mode_name, context)
semantics = scene_semantic_guidance(mode_name)
@@ -497,7 +520,109 @@ def test_romantic_and_mid_autumn_require_flashing_light_actions(
context["scene_semantics"] = semantics
schema = build_scene_output_schema(context)
assert required == ["ir:flash-open", "ir:flash-red"]
assert schema["properties"]["requests"]["maxItems"] == 10
assert required == [
"ir:flash-open",
"ir:strip-open",
]
assert scene_required_peripheral_refs(
mode_name,
context,
include_default_bundle=True,
) == [
"ir:flash-open",
"ir:ambient-open",
"ir:strip-open",
]
assert schema["properties"]["requests"]["maxItems"] == 18
if "中秋" in mode_name:
assert semantics["family"] == "festival_celebration"
@pytest.mark.parametrize(
("mode_name", "expected_shade"),
(("浪漫模式", 0), ("中秋欢快模式", 100)),
)
def test_required_native_fallbacks_cover_climate_ambient_and_shade(
mode_name: str,
expected_shade: int,
) -> None:
context = _context()
context["capabilities"].append(
{
"id": "ambient_light.set_power",
"domain": "ambient_light",
"target_scopes": ["vehicle"],
"parameters": [
{
"name": "state",
"type": "string",
"allowed_values": ["on", "off"],
"required": True,
}
],
}
)
fallbacks = scene_required_native_fallbacks(mode_name, context)
assert [item["domain"] for item in fallbacks] == [
"climate",
"ambient_light",
"roof",
]
assert fallbacks[0]["capability"] == "climate.set_temperature"
assert fallbacks[1]["capability"] == "ambient_light.set_power"
assert fallbacks[2]["capability"] == "roof.set_shade_position"
assert fallbacks[2]["parameters"] == [
{"name": "position_pct", "value": expected_shade}
]
def test_name_only_scene_default_bundle_covers_all_required_native_controls() -> None:
service = SeatDemoService()
catalog = AssistantCapabilityCatalog(service)
context = catalog.scene_composition_context(catalog.snapshot())
fallbacks = scene_required_native_fallbacks(
"星夜模式",
context,
include_default_bundle=True,
)
semantics = scene_semantic_guidance("星夜模式")
semantics["native_fallback_requests"] = fallbacks
semantics["peripheral_policy"] = {"required_refs": []}
context["scene_semantics"] = semantics
assert [(item["capability"], item["target_scope"]) for item in fallbacks] == [
("climate.set_power", "vehicle"),
("climate.set_temperature", "vehicle"),
("climate.set_fan_level", "vehicle"),
("climate.set_cycle_mode", "vehicle"),
("window.set_position", "front_left"),
("window.set_position", "front_right"),
("window.set_position", "rear_left"),
("window.set_position", "rear_right"),
("roof.set_shade_position", "vehicle"),
("seat.set_ventilation", "passenger"),
("seat.set_backrest_recline", "passenger"),
("seat.set_legrest_height", "passenger"),
("ambient_light.set_power", "vehicle"),
]
assert build_scene_output_schema(context)["properties"]["requests"]["maxItems"] == 7
@pytest.mark.parametrize(
("message", "expected"),
(
("创建浪漫中秋模式", False),
("创建浪漫中秋模式,空调温度设置为25度", True),
("创建灯光主题模式", True),
("创建主驾浪漫模式", True),
("创建节日模式", False),
),
)
def test_scene_detects_whether_user_named_a_concrete_control_object(
message: str,
expected: bool,
) -> None:
assert scene_has_explicit_control_object(message, _context()) is expected