feat: make mode creation preview-only and cache-safe
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user