feat: 完善 N7 智能座舱交互与控制链路

This commit is contained in:
vee
2026-09-07 15:34:59 +08:00
parent 32d179143f
commit c96970f068
100 changed files with 30088 additions and 1174 deletions
+215
View File
@@ -371,6 +371,221 @@ class Can1SemanticWhitelistTests(unittest.TestCase):
24,
)
def test_chinese_compressor_request_is_not_collapsed_into_hvac_power(self) -> None:
cases = (
("打开空调压缩机", "on"),
("空调压缩机设为开启状态", "on"),
("关闭空调压缩机", "off"),
("空调压缩机设置为关闭状态", "off"),
)
for index, (utterance, expected_state) in enumerate(cases):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-can-one-compressor-{index}",
execution_mode="dry_run",
)
self.assertEqual(result["status"], "succeeded")
actions = result["intent_ir"]["spec"]["actions"]
self.assertEqual(len(actions), 1)
self.assertEqual(actions[0]["capability"], "climate.set_ac")
self.assertEqual(actions[0]["parameters"], {"state": expected_state})
def test_location_aliases_never_redirect_to_the_wrong_default_target(self) -> None:
recognized = (
("后座车窗打开", ["window rear open"]),
("二排车窗打开", ["window rear open"]),
("后排左侧车窗打开", ["window rear-left open"]),
("后排右侧车窗打开", ["window rear-right open"]),
("后座空调温度设为25度", ["ac temp rear 25"]),
("二排空调温度设为25度", ["ac temp rear 25"]),
)
for index, (utterance, expected) in enumerate(recognized):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-location-alias-{index}",
execution_mode="dry_run",
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(self._debug_commands(result), expected)
unsupported = (
"第三排车窗打开",
"左侧车窗打开",
"左侧空调温度设为25度",
"打开主驾阅读灯",
"打开驾驶员阅读灯",
"打开前排阅读灯",
"打开后排阅读灯",
"打开二排座椅通风",
)
for index, utterance in enumerate(unsupported):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-location-reject-{index}",
execution_mode="dry_run",
)
self.assertEqual(self._debug_commands(result), [])
self.assertEqual(result["intent_ir"]["spec"]["actions"], [])
passenger = self.service.process(
"乘员座椅加热2档",
provider="local",
conversation_id="conv-location-passenger-alias",
execution_mode="dry_run",
)
passenger_actions = passenger["intent_ir"]["spec"]["actions"]
self.assertEqual(passenger["status"], "succeeded")
self.assertEqual(
[
(action["capability"], action["target"]["zone"])
for action in passenger_actions
],
[("seat.set_heating", "front_right")],
)
def test_multi_zone_temperature_values_remain_bound_to_their_clauses(self) -> None:
cases = (
(
"主驾温度22度,副驾温度24度",
["ac temp driver 22", "ac temp passenger 24"],
),
(
"副驾温度24度,主驾温度22度",
["ac temp passenger 24", "ac temp driver 22"],
),
(
"主驾风量3档,副驾温度24度",
["ac temp passenger 24"],
),
)
for index, (utterance, expected) in enumerate(cases):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-climate-clause-binding-{index}",
execution_mode="dry_run",
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(self._debug_commands(result), expected)
def test_narrow_unsupported_climate_targets_never_widen_to_a_valid_zone(self) -> None:
unsupported = (
"左后空调温度22度",
"后排左侧空调温度22度",
"后排风量3档",
"后排内循环",
"主驾氛围灯打开",
)
for index, utterance in enumerate(unsupported):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-climate-scope-reject-{index}",
execution_mode="dry_run",
)
self.assertEqual(self._debug_commands(result), [])
self.assertEqual(result["intent_ir"]["spec"]["actions"], [])
def test_explicit_outlet_locations_never_fall_back_to_driver_left(self) -> None:
unsupported = (
"副驾出风口打开",
"副驾出风口左右50%上下50%",
"副驾出风口标定坐标左右20上下30",
"后排出风口打开",
"后排出风口左右50%上下50%",
"后排出风口标定坐标左右20上下30",
"驾驶员出风口打开",
"驾驶员出风口左右50%上下50%",
"驾驶员出风口标定坐标左右20上下30",
)
for index, utterance in enumerate(unsupported):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-outlet-location-reject-{index}",
execution_mode="dry_run",
)
self.assertEqual(self._debug_commands(result), [])
self.assertEqual(result["intent_ir"]["spec"]["actions"], [])
def test_meta_language_never_authorizes_embedded_vehicle_commands(self) -> None:
utterances = (
"请复述:打开遮阳帘",
"把‘打开空调’翻译成英文",
"写一个故事,主角打开空调",
"用‘打开主驾车窗’造句",
)
for index, utterance in enumerate(utterances):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-meta-language-{index}",
execution_mode="dry_run",
)
self.assertEqual(self._debug_commands(result), [])
self.assertEqual(result["intent_ir"]["spec"]["actions"], [])
self.assertIn(
"meta_language_is_not_vehicle_authorization",
{
item["reason"]
for item in result["intent_ir"]["spec"]["unresolved_spans"]
},
)
def test_zoned_hvac_requests_never_expand_to_vehicle_wide_can(self) -> None:
for index, utterance in enumerate(
(
"把副驾空调设为吹脚",
"后排空调设为吹面",
"主驾内循环",
"副驾风量设为2档",
"后排空调设为自动模式",
)
):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-zoned-hvac-reject-{index}",
execution_mode="dry_run",
)
self.assertEqual(self._debug_commands(result), [])
self.assertEqual(result["intent_ir"]["spec"]["actions"], [])
def test_localized_requests_never_expand_to_whole_vehicle_devices(self) -> None:
utterances = (
"左后门上锁",
"右后门解锁",
"主驾车门上锁",
"后排遮阳帘打开",
"左侧遮阳帘打开",
"主驾室内灯打开",
"后排车内灯打开",
"副驾氛围灯打开",
"后排氛围灯亮度设为3档",
)
for index, utterance in enumerate(utterances):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
provider="local",
conversation_id=f"conv-whole-target-reject-{index}",
execution_mode="dry_run",
)
self.assertEqual(self._debug_commands(result), [])
self.assertEqual(result["intent_ir"]["spec"]["actions"], [])
def test_disabling_one_outlet_feature_never_enables_that_mode(self) -> None:
for index, utterance in enumerate(
("关闭吹面出风口", "把吹面出风口关闭")