feat: add seat-scoped static and dynamic assistant modes
This commit is contained in:
@@ -144,7 +144,7 @@ def test_all_production_scene_templates_complete_the_full_local_dry_run(
|
||||
templates = snapshot["scene_templates"]
|
||||
|
||||
assert isinstance(templates, list)
|
||||
assert len(templates) == 13
|
||||
assert len(templates) == 15
|
||||
assert all(template["assistant_callable"] is True for template in templates)
|
||||
|
||||
with patch.object(
|
||||
@@ -169,11 +169,30 @@ def test_all_production_scene_templates_complete_the_full_local_dry_run(
|
||||
assert result["orchestration_route"] == "mode_profile_create_preview"
|
||||
draft = result["mode_profile_draft"]
|
||||
assert draft["generation_source"] == "scene_template_copy"
|
||||
assert draft["operation_count"] == template["operation_count"]
|
||||
assert draft["source_template_id"] == template["id"]
|
||||
assert draft["source_template_revision"] == template["template_revision"]
|
||||
assert "existing_mode_id" not in draft
|
||||
|
||||
expected_requests = plan["requests"]
|
||||
if plan.get("schedule"):
|
||||
expected_schedule = deepcopy(plan["schedule"])
|
||||
for phase in expected_schedule["phases"]:
|
||||
phase["operations"] = [
|
||||
op for op in phase["operations"]
|
||||
if op["domain"] != "seat" or op["target_scope"] == "passenger"
|
||||
]
|
||||
assert draft["schedule"] == expected_schedule
|
||||
expected_requests = [
|
||||
{**op, "parameters": [{"name": key, "value": value}
|
||||
for key, value in op["parameters"].items()]}
|
||||
for phase in expected_schedule["phases"] for op in phase["operations"]
|
||||
]
|
||||
else:
|
||||
expected_requests = [
|
||||
request for request in expected_requests
|
||||
if request["domain"] != "seat" or request["target_scope"] == "passenger"
|
||||
]
|
||||
assert draft["operation_count"] == len(expected_requests)
|
||||
expected = {
|
||||
(
|
||||
str(request["capability"]),
|
||||
@@ -187,7 +206,7 @@ def test_all_production_scene_templates_complete_the_full_local_dry_run(
|
||||
sort_keys=True,
|
||||
),
|
||||
)
|
||||
for request in plan["requests"]
|
||||
for request in expected_requests
|
||||
}
|
||||
actual = {
|
||||
(
|
||||
@@ -311,7 +330,10 @@ def test_purpose_descriptions_use_a_concise_name_and_zero_model_template_route(
|
||||
assert draft["name"] == expected_name
|
||||
assert draft["generation_source"] == "scene_template_copy"
|
||||
assert draft["source_template_id"] == template_id
|
||||
assert draft["operation_count"] == len(template.operations)
|
||||
assert draft["operation_count"] == sum(
|
||||
operation.domain != "seat" or operation.target_scope == "passenger"
|
||||
for operation in template.operations
|
||||
)
|
||||
assert passed_plans[0]["metadata"]["template_id"] == template_id
|
||||
assert events[0]["engine"] == "n7web-scene-template"
|
||||
assert not list(user_root.rglob("*.yaml"))
|
||||
@@ -353,7 +375,7 @@ def test_explicit_settings_on_a_purpose_scene_bypass_template_defaults(
|
||||
("构建一个长途舒适模式", "长途舒适模式", "long-trip-comfort"),
|
||||
),
|
||||
)
|
||||
def test_seating_comfort_requests_preview_both_seats_with_no_model_or_hardware_call(
|
||||
def test_seating_comfort_requests_preview_only_passenger_with_no_model_or_hardware_call(
|
||||
hybrid_service: tuple[SeatDemoService, AssistantCapabilityCatalog, Path],
|
||||
message: str,
|
||||
expected_name: str,
|
||||
@@ -380,16 +402,13 @@ def test_seating_comfort_requests_preview_both_seats_with_no_model_or_hardware_c
|
||||
for (capability, target), parameters in _action_map(result).items()
|
||||
if capability.startswith("seat.")
|
||||
}
|
||||
assert {target for _capability, target in seat_actions} == {"driver", "passenger"}
|
||||
assert {target for _capability, target in seat_actions} == {"passenger"}
|
||||
assert all(
|
||||
"driver_axis" not in capability and "driver_position" not in capability
|
||||
for capability, _target in seat_actions
|
||||
)
|
||||
assert ("seat.set_driver_massage_native", "passenger") not in seat_actions
|
||||
if template_id in {"seat-comfort", "long-trip-comfort"}:
|
||||
assert seat_actions["seat.set_driver_ventilation_native", "driver"] == {
|
||||
"state": "on", "level": 2,
|
||||
}
|
||||
assert seat_actions["seat.set_ventilation", "passenger"] == {
|
||||
"state": "on", "level": 1,
|
||||
}
|
||||
@@ -422,7 +441,7 @@ def test_unregistered_seat_scene_keeps_both_explicit_targets_through_native_merg
|
||||
side_effect=AssertionError("scene composition reached hardware execution"),
|
||||
):
|
||||
result = service.preview_native_can(
|
||||
f"构建一个{name}", provider="local", conversation_id="conv-seat-generated",
|
||||
f"构建一个主驾和副驾的{name}", provider="local", conversation_id="conv-seat-generated",
|
||||
execution_mode="hardware", vehicle_id="denza_n7", assistant_plan=plan,
|
||||
)
|
||||
assert result["status"] == "succeeded"
|
||||
@@ -437,7 +456,7 @@ def test_unregistered_seat_scene_keeps_both_explicit_targets_through_native_merg
|
||||
assert not list(user_root.rglob("*.yaml"))
|
||||
|
||||
|
||||
def test_explicit_unscoped_seat_instruction_keeps_target_ambiguity_guard(
|
||||
def test_unscoped_seat_instruction_inside_mode_creation_defaults_to_passenger(
|
||||
hybrid_service: tuple[SeatDemoService, AssistantCapabilityCatalog, Path],
|
||||
) -> None:
|
||||
service, _catalog, _user_root = hybrid_service
|
||||
@@ -446,8 +465,11 @@ def test_explicit_unscoped_seat_instruction_keeps_target_ambiguity_guard(
|
||||
conversation_id="conv-seat-explicit-target", execution_mode="hardware",
|
||||
vehicle_id="denza_n7",
|
||||
)
|
||||
assert result["status"] != "succeeded"
|
||||
assert result.get("mode_profile_draft") is None
|
||||
assert result["status"] == "succeeded"
|
||||
assert _action_map(result) == {
|
||||
("seat.set_backrest_recline", "passenger"): {"position_pct": 45},
|
||||
}
|
||||
assert result.get("mode_profile_draft")
|
||||
assert result["hardware_execution_allowed"] is False
|
||||
|
||||
|
||||
@@ -552,7 +574,7 @@ def test_template_copy_can_be_revised_twice_without_losing_sibling_actions(
|
||||
assert shade_revised["execution_mode"] == final["execution_mode"] == "dry_run"
|
||||
assert shade_revised["hardware_execution_allowed"] is False
|
||||
assert final["hardware_execution_allowed"] is False
|
||||
assert len(built_actions) == len(shade_actions) == len(final_actions) == 7
|
||||
assert len(built_actions) == len(shade_actions) == len(final_actions) == 10
|
||||
assert built_actions[shade_key] == {"position_pct": 0}
|
||||
assert shade_actions[shade_key] == final_actions[shade_key] == {"position_pct": 100}
|
||||
assert built_actions[temperature_key] == shade_actions[temperature_key] == {"temperature_c": 24}
|
||||
|
||||
Reference in New Issue
Block a user