feat: add seat-scoped static and dynamic assistant modes

This commit is contained in:
vee
2026-09-12 14:56:30 +08:00
parent d09b5967f8
commit d8dad22ec0
60 changed files with 5847 additions and 149 deletions
+36 -14
View File
@@ -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}