完善模式卡片、NFC及多设备控制流程
This commit is contained in:
@@ -621,7 +621,7 @@ operations:
|
||||
if item["id"] == "office"
|
||||
)
|
||||
self.assertEqual(persisted["name"], "专注办公模式")
|
||||
with self.assertRaisesRegex(ValueError, "重新点击执行"):
|
||||
with self.assertRaisesRegex(ValueError, "生成指令"):
|
||||
self.service.save_mode_profile_card(
|
||||
"office",
|
||||
"专注办公模式",
|
||||
@@ -630,6 +630,181 @@ operations:
|
||||
"denza_n7",
|
||||
)
|
||||
|
||||
def test_saved_mode_card_executes_without_reinterpreting_instruction(self) -> None:
|
||||
mode_root = Path(self.temporary_directory.name) / "direct-mode-presets"
|
||||
user_root = Path(self.temporary_directory.name) / "direct-mode-user"
|
||||
preset = mode_root / "vehicles" / "denza_n7" / "office.yaml"
|
||||
preset.parent.mkdir(parents=True)
|
||||
preset.write_text(
|
||||
"""
|
||||
id: office
|
||||
name: 办公模式
|
||||
icon: briefcase
|
||||
scope:
|
||||
vehicle_ids: [denza_n7]
|
||||
operations:
|
||||
- domain: climate
|
||||
capability: climate.set_temperature
|
||||
target_scope: driver
|
||||
parameters:
|
||||
temperature_c: 24
|
||||
""".strip()
|
||||
+ "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
self.service.mode_profiles = ModeProfileRegistry(
|
||||
mode_root, user_root=user_root
|
||||
)
|
||||
instruction = "空调温度设置为25度,风速设置为1档"
|
||||
generated = self.service.preview_native_can(
|
||||
instruction,
|
||||
provider="local",
|
||||
conversation_id="conv-generate-office-card",
|
||||
execution_mode="dry_run",
|
||||
vehicle_id="denza_n7",
|
||||
)
|
||||
saved = self.service.save_mode_profile_card(
|
||||
"office",
|
||||
"办公模式",
|
||||
instruction,
|
||||
generated["request_id"],
|
||||
"denza_n7",
|
||||
)
|
||||
|
||||
with patch.object(
|
||||
self.service,
|
||||
"_interpret",
|
||||
side_effect=AssertionError("saved mode must not reinterpret natural language"),
|
||||
):
|
||||
executed = self.service.execute_mode_profile_card(
|
||||
"office",
|
||||
conversation_id="conv-execute-office-card",
|
||||
execution_mode="dry_run",
|
||||
vehicle_id="denza_n7",
|
||||
)
|
||||
|
||||
operations = [
|
||||
operation
|
||||
for config in executed.get("function_configs", {}).values()
|
||||
for operation in config.get("spec", {}).get("operations", [])
|
||||
]
|
||||
self.assertEqual(executed["status"], "succeeded")
|
||||
self.assertEqual(executed["utterance"], "办公模式")
|
||||
self.assertEqual(executed["provider_used"], "saved_mode_command_flow")
|
||||
self.assertEqual(executed["orchestration_route"], "saved_mode_command_flow")
|
||||
self.assertEqual(
|
||||
[
|
||||
(
|
||||
operation["capability"],
|
||||
operation["target"]["zone"],
|
||||
operation["parameters"],
|
||||
operation["parse_source"],
|
||||
)
|
||||
for operation in operations
|
||||
],
|
||||
[
|
||||
(
|
||||
"climate.set_temperature",
|
||||
"driver",
|
||||
{"temperature_c": 25},
|
||||
"saved_mode_command_flow",
|
||||
),
|
||||
(
|
||||
"climate.set_fan_level",
|
||||
"vehicle",
|
||||
{"level": 1},
|
||||
"saved_mode_command_flow",
|
||||
),
|
||||
],
|
||||
)
|
||||
self.assertEqual(
|
||||
saved["mode_profile"]["command_flow"]["execution_steps"], []
|
||||
)
|
||||
|
||||
def test_saved_mode_card_replays_front_right_dynamic_target_as_passenger(
|
||||
self,
|
||||
) -> None:
|
||||
mode_root = Path(self.temporary_directory.name) / "dynamic-mode-presets"
|
||||
user_root = Path(self.temporary_directory.name) / "dynamic-mode-user"
|
||||
self.service.mode_profiles = ModeProfileRegistry(
|
||||
mode_root,
|
||||
user_root=user_root,
|
||||
)
|
||||
self.service.mode_profiles.save_mode(
|
||||
"小憩模式",
|
||||
[
|
||||
{
|
||||
"domain": "seat",
|
||||
"capability": "seat.start_dynamic_mode",
|
||||
"target_scope": "front_right",
|
||||
"parameters": {"mode_id": 2},
|
||||
},
|
||||
{
|
||||
"domain": "climate",
|
||||
"capability": "climate.set_power",
|
||||
"target_scope": "vehicle",
|
||||
"parameters": {"state": "on"},
|
||||
},
|
||||
{
|
||||
"domain": "roof",
|
||||
"capability": "roof.set_shade_motion",
|
||||
"target_scope": "vehicle",
|
||||
"parameters": {"motion": "open"},
|
||||
},
|
||||
],
|
||||
mode_id="nap",
|
||||
vehicle_id="denza_n7",
|
||||
instruction="打开摇篮模式,开启空调",
|
||||
command_flow={
|
||||
"schema": "cognitive-agent-mode-command-flow/v1",
|
||||
"source_request_id": "req-saved-dynamic-mode",
|
||||
"plans": {
|
||||
"local_seat": {
|
||||
"spec": {
|
||||
"commands": [
|
||||
{
|
||||
"message": "Seat_Dynamic_Mode_Virtual",
|
||||
"signals": {"Dynamic_Mode_ID": 2},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
with patch.object(
|
||||
self.service,
|
||||
"_interpret",
|
||||
side_effect=AssertionError("saved mode must not reinterpret natural language"),
|
||||
):
|
||||
executed = self.service.execute_mode_profile_card(
|
||||
"nap",
|
||||
conversation_id="conv-execute-saved-dynamic-card",
|
||||
execution_mode="dry_run",
|
||||
vehicle_id="denza_n7",
|
||||
)
|
||||
|
||||
self.assertEqual(executed["status"], "succeeded")
|
||||
self.assertEqual(executed["utterance"], "小憩模式")
|
||||
self.assertEqual(executed["provider_used"], "saved_mode_command_flow")
|
||||
self.assertFalse(
|
||||
[item for item in executed.get("validation", []) if item["severity"] == "error"]
|
||||
)
|
||||
dynamic_request = next(
|
||||
item
|
||||
for item in executed["model_requests"]
|
||||
if item["capability"] == "seat.start_dynamic_mode"
|
||||
)
|
||||
self.assertEqual(dynamic_request["target_scope"], "passenger")
|
||||
self.assertTrue(executed["command_plans"])
|
||||
replayed_capabilities = {
|
||||
operation["capability"]
|
||||
for config in executed["function_configs"].values()
|
||||
for operation in config["spec"]["operations"]
|
||||
}
|
||||
self.assertIn("roof.set_shade_motion", replayed_capabilities)
|
||||
|
||||
def test_build_named_mode_executes_and_persists_in_one_turn(self) -> None:
|
||||
mode_root = Path(self.temporary_directory.name) / "modes"
|
||||
self.service.mode_profiles = ModeProfileRegistry(mode_root)
|
||||
|
||||
Reference in New Issue
Block a user