Files
Cognitive_Agent/tests/integration/test_multidomain_service.py

743 lines
29 KiB
Python
Executable File

from __future__ import annotations
import tempfile
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
from cognitive_agent.application.domain_runtime import ConfiguredDomainRuntime
from cognitive_agent.application.mode_profile import ModeProfileRegistry
from cognitive_agent.application.seat_service import REPOSITORY_ROOT, SeatDemoService
class ConfiguredDomainRuntimeTests(unittest.TestCase):
def test_matrix_backed_domain_frames(self) -> None:
cases = {
"climate": (
[
{
"domain": "climate",
"capability": "climate.set_temperature",
"target": "driver",
"parameters": {"temperature_c": 22},
"operation": "set",
"reason": "test",
},
{
"domain": "climate",
"capability": "climate.set_fan_level",
"target": "vehicle",
"parameters": {"level": 3},
"operation": "set",
"reason": "test",
},
],
["05 16 00 00 00 00 00 00", "04 04 00 00 00 00 00 00"],
),
"roof": (
[
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target": "vehicle",
"parameters": {"transmittance_pct": 30},
"operation": "set",
"reason": "test",
},
{
"domain": "roof",
"capability": "roof.set_shade_position",
"target": "vehicle",
"parameters": {"position_pct": 60},
"operation": "set",
"reason": "test",
},
],
["13 00 1E 00", "04 00 00 00 3C"],
),
"ambient_light": (
[
{
"domain": "ambient_light",
"capability": "ambient_light.set_illumination",
"target": "vehicle",
"parameters": {
"color_hex": "#FF8040",
"brightness_pct": 60,
},
"operation": "set",
"reason": "test",
}
],
["2B FF 80 40 3C"],
),
}
for domain, (actions, expected_frames) in cases.items():
with self.subTest(domain=domain):
runtime = ConfiguredDomainRuntime(REPOSITORY_ROOT, domain)
config = runtime.build_function_config(
actions, "req-test-domain-frame", "test"
)
plan = runtime.compile(config)
report = runtime.execute(plan, config)
frames = [
item["telemetry"]["command_frame"]["data_hex"]
for item in report["spec"]["results"]
]
self.assertEqual(frames, expected_frames)
class MultiDomainServiceTests(unittest.TestCase):
def setUp(self) -> None:
self.service = SeatDemoService(REPOSITORY_ROOT)
self.service.openai.api_key = "test-key"
self.temporary_directory = tempfile.TemporaryDirectory()
self.addCleanup(self.temporary_directory.cleanup)
self.service.artifact_root = Path(self.temporary_directory.name)
def test_four_domain_scene_is_generated_executed_and_persisted(self) -> None:
model_output = {
"detected_domains": ["seat", "climate", "roof", "ambient_light"],
"requests": [
{
"domain": "seat",
"capability": "seat.set_backrest_recline",
"target_scope": "passenger",
"operation": "set",
"parameters": [{"name": "position_pct", "value": 55}],
"reason": "comfortable viewing posture",
},
{
"domain": "climate",
"capability": "climate.set_temperature",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "temperature_c", "value": 24}],
"reason": "comfortable cabin",
},
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "transmittance_pct", "value": 20}],
"reason": "reduce glare",
},
{
"domain": "ambient_light",
"capability": "ambient_light.set_illumination",
"target_scope": "vehicle",
"operation": "set",
"parameters": [
{"name": "color_hex", "value": "#FF8040"},
{"name": "brightness_pct", "value": 35},
],
"reason": "warm cinema lighting",
},
],
"ambiguities": [],
"decision_summary": ["生成四域观影目标。"],
"confidence": 0.95,
}
with patch.object(self.service.openai, "interpret", return_value=model_output):
result = self.service.process(
"进入观影状态",
"openai",
"conv-four-domain-test",
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(
set(result["function_configs"]),
{"seat", "climate", "roof", "ambient_light"},
)
self.assertEqual(len(result["scene_config"]["spec"]["function_refs"]), 4)
self.assertEqual(
{item["domain"] for item in result["execution_report"]["spec"]["results"]},
{"seat", "climate", "roof", "ambient_light"},
)
self.assertEqual(result["domain_state"]["roof"]["transmittance_pct"], 20)
self.assertEqual(
result["domain_state"]["ambient_light"]["color_hex"], "#FF8040"
)
run_path = self.service.artifact_root / result["request_id"]
self.assertTrue((run_path / "scene.yaml").is_file())
for domain in ("seat", "climate", "roof", "ambient_light"):
self.assertTrue((run_path / "functions" / f"{domain}.yaml").is_file())
self.assertTrue(
(run_path / "command-plans" / f"{domain}.yaml").is_file()
)
def test_domain_state_is_supplied_to_follow_up_model_turn(self) -> None:
first_plan = {
"detected_domains": ["roof"],
"requests": [
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "transmittance_pct", "value": 30}],
"reason": "initial target",
}
],
"ambiguities": [],
"decision_summary": ["天幕透光率设为30%。"],
"confidence": 0.96,
}
second_plan = {
**first_plan,
"requests": [
{
**first_plan["requests"][0],
"operation": "decrease",
"parameters": [{"name": "transmittance_pct", "value": 20}],
"reason": "resolved relative to current 30 percent",
}
],
"decision_summary": ["基于当前30%继续调暗到20%。"],
}
with patch.object(
self.service.openai,
"interpret",
side_effect=[first_plan, second_plan],
) as interpret:
self.service.process(
"天幕透光率调到30%",
"openai",
"conv-roof-follow-up",
)
result = self.service.process(
"再暗一点",
"openai",
"conv-roof-follow-up",
)
second_context = interpret.call_args_list[1].args[1]
self.assertEqual(
second_context["domain_devices"]["roof"]["transmittance_pct"], 30
)
self.assertEqual(result["domain_state"]["roof"]["transmittance_pct"], 20)
self.assertEqual(result["conversation_turn"], 2)
def test_named_mode_profile_executes_without_model_expansion(self) -> None:
model_output = {
"detected_domains": ["seat"],
"requests": [],
"ambiguities": [],
"decision_summary": ["用户要求调用已有零重力模式。"],
"confidence": 0.94,
}
with patch.object(self.service.openai, "interpret", return_value=model_output):
result = self.service.process(
"副驾驶进入零重力模式",
"openai",
"conv-zero-gravity-mode",
vehicle_id="denza_n7",
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(result["matched_modes"][0]["id"], "zero_gravity")
operations = result["function_config"]["spec"]["operations"]
by_capability = {item["capability"]: item for item in operations}
self.assertEqual(
by_capability["seat.set_longitudinal_position"]["parameters"],
{"position_pct": 100},
)
self.assertEqual(
by_capability["seat.set_cushion_tilt"]["parameters"],
{"position_pct": 100},
)
self.assertEqual(
by_capability["seat.set_backrest_recline"]["parameters"],
{"position_pct": 81, "angle_deg": 150},
)
self.assertEqual(
by_capability["seat.set_legrest_height"]["parameters"],
{"position_pct": 94, "angle_deg": 163},
)
def test_named_mode_profile_suppresses_generic_local_parser_ambiguity(self) -> None:
result = self.service.process(
"副驾进入零重力模式",
"local",
"conv-zero-gravity-local-mode",
vehicle_id="denza_n7",
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(result["matched_modes"][0]["id"], "zero_gravity")
self.assertFalse(
any(
issue.get("code") == "AMBIGUOUS_INTENT"
for issue in result["validation"]
)
)
def test_named_mode_profile_combines_with_temporary_roof_request(self) -> None:
model_output = {
"detected_domains": ["roof"],
"requests": [
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "transmittance_pct", "value": 20}],
"reason": "用户同时要求天幕调暗。",
}
],
"ambiguities": [],
"decision_summary": ["零重力之外还需设置天幕。"],
"confidence": 0.96,
}
with patch.object(self.service.openai, "interpret", return_value=model_output):
result = self.service.process(
"副驾零重力模式,天幕透光率调到20%",
"openai",
"conv-mode-plus-roof",
vehicle_id="denza_n7",
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(set(result["function_configs"]), {"seat", "roof"})
self.assertEqual(result["scene_config"]["kind"], "SceneConfig")
self.assertEqual(result["domain_state"]["roof"]["transmittance_pct"], 20)
self.assertIn(
"seat.set_backrest_recline",
{
item["capability"]
for item in result["function_configs"]["seat"]["spec"]["operations"]
},
)
def test_hardware_orchestration_uses_physical_passenger_seat_and_virtual_roof(
self,
) -> None:
model_output = {
"detected_domains": ["seat", "roof"],
"requests": [
{
"domain": "seat",
"capability": "seat.set_backrest_recline",
"target_scope": "passenger",
"operation": "set",
"parameters": [{"name": "position_pct", "value": 55}],
"reason": "调整副驾靠背。",
},
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "transmittance_pct", "value": 20}],
"reason": "降低天幕透光率。",
},
],
"ambiguities": [],
"decision_summary": ["执行副驾与天幕联合模式。"],
"confidence": 0.96,
}
physical_state = {
"position": {
"longitudinal": {"position_pct": 51, "position_valid": True},
"cushion_tilt": {"position_pct": 11, "position_valid": True},
"backrest_recline": {"position_pct": 54, "position_valid": True},
"legrest_height": {"position_pct": 0, "position_valid": True},
},
"ventilation": {"state": "off", "level": 0},
"heating": {"state": "off", "level": 0},
"captured_at": "2026-07-31T04:00:00Z",
"complete": True,
"missing": [],
}
def execute_hardware(plan, config, devices):
del plan, devices
operation = config["spec"]["operations"][0]
return {
"apiVersion": "cognitive-agent/v1alpha1",
"kind": "ExecutionReport",
"metadata": {
"id": "report-hardware-test",
"name": "T2G seat hardware execution report",
"version": "1.0.0",
"request_id": config["metadata"]["request_id"],
"labels": {"simulation": "false"},
},
"spec": {
"mode": "hil",
"status": "succeeded",
"started_at": "2026-07-31T04:00:00Z",
"finished_at": "2026-07-31T04:00:01Z",
"physical_state": physical_state,
"results": [
{
"ref": operation["id"],
"domain": "seat",
"status": "succeeded",
"message": "physical target reached",
"telemetry": {
"motion_axis": "backrest_recline",
"effective_position_pct": 54,
"position_valid": True,
"simulated": False,
},
}
],
},
}
hardware_executor = MagicMock()
hardware_executor.execute.side_effect = execute_hardware
initial_driver_backrest = self.service.conversations.snapshot(
"conv-mixed-hardware-success"
)["devices"]["driver"]["position"]["backrest_recline"]["position_pct"]
with (
patch.object(self.service.openai, "interpret", return_value=model_output),
patch.object(type(self.service.hardware_settings), "authorize"),
patch.object(
type(self.service.hardware_settings),
"validate_function_config",
),
patch.object(
self.service,
"_new_hardware_executor",
return_value=hardware_executor,
) as executor_factory,
):
result = self.service.process(
"副驾靠背调到55%,天幕透光率调到20%",
"openai",
"conv-mixed-hardware-success",
execution_mode="hardware",
approval_token="test-token",
vehicle_id="denza_n7",
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(result["execution_report"]["spec"]["mode"], "hil")
self.assertEqual(
result["execution_report"]["metadata"]["labels"]["simulation"],
"mixed",
)
executor_factory.assert_called_once_with()
hardware_executor.execute.assert_called_once()
by_domain = {
item["domain"]: item
for item in result["execution_report"]["spec"]["results"]
}
self.assertFalse(by_domain["seat"]["telemetry"]["simulated"])
self.assertTrue(by_domain["roof"]["telemetry"]["simulated"])
self.assertEqual(
result["actuator_state"]["passenger"]["position"][
"backrest_recline"
]["position_pct"],
54,
)
self.assertEqual(
result["actuator_state"]["driver"]["position"]["backrest_recline"][
"position_pct"
],
initial_driver_backrest,
)
self.assertEqual(result["domain_state"]["roof"]["transmittance_pct"], 20)
def test_hardware_orchestration_failure_still_synchronizes_physical_seat(
self,
) -> None:
model_output = {
"detected_domains": ["seat", "roof"],
"requests": [
{
"domain": "seat",
"capability": "seat.set_longitudinal_position",
"target_scope": "passenger",
"operation": "set",
"parameters": [{"name": "position_pct", "value": 100}],
"reason": "移动副驾。",
},
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "transmittance_pct", "value": 20}],
"reason": "降低天幕透光率。",
},
],
"ambiguities": [],
"decision_summary": ["执行副驾与天幕联合模式。"],
"confidence": 0.96,
}
hardware_executor = MagicMock()
def execute_hardware(plan, config, devices):
del plan, devices
return {
"apiVersion": "cognitive-agent/v1alpha1",
"kind": "ExecutionReport",
"metadata": {
"id": "report-hardware-failure-test",
"name": "T2G seat hardware execution report",
"version": "1.0.0",
"request_id": config["metadata"]["request_id"],
"labels": {"simulation": "false"},
},
"spec": {
"mode": "hil",
"status": "failed",
"started_at": "2026-07-31T04:00:00Z",
"finished_at": "2026-07-31T04:00:01Z",
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 63,
"position_valid": True,
}
},
"captured_at": "2026-07-31T04:00:01Z",
"complete": False,
"missing": ["cushion_tilt", "backrest_recline", "legrest_height"],
},
"results": [
{
"ref": config["spec"]["operations"][0]["id"],
"domain": "seat",
"status": "failed",
"message": "Motor0 TIMEOUT",
"telemetry": {"simulated": False},
}
],
},
}
hardware_executor.execute.side_effect = execute_hardware
initial_roof = self.service.conversations.snapshot(
"conv-mixed-hardware-failure"
)["domain_devices"]["roof"]["transmittance_pct"]
with (
patch.object(self.service.openai, "interpret", return_value=model_output),
patch.object(type(self.service.hardware_settings), "authorize"),
patch.object(
type(self.service.hardware_settings),
"validate_function_config",
),
patch.object(
self.service,
"_new_hardware_executor",
return_value=hardware_executor,
),
):
result = self.service.process(
"副驾水平移到100%,天幕透光率调到20%",
"openai",
"conv-mixed-hardware-failure",
execution_mode="hardware",
approval_token="test-token",
vehicle_id="denza_n7",
)
self.assertEqual(result["status"], "execution_failed")
self.assertEqual(result["execution_report"]["spec"]["status"], "failed")
self.assertEqual(
result["actuator_state"]["passenger"]["position"]["longitudinal"][
"position_pct"
],
63,
)
self.assertEqual(
result["actuator_state"]["passenger"]["position"]["longitudinal"][
"feedback_source"
],
"physical_can",
)
self.assertEqual(
result["domain_state"]["roof"]["transmittance_pct"],
initial_roof,
)
def test_reference_mode_library_modes_execute_for_denza(self) -> None:
model_output = {
"detected_domains": ["seat"],
"requests": [],
"ambiguities": [],
"decision_summary": ["用户要求调用已有长期模式。"],
"confidence": 0.95,
}
utterances = [
"副驾驶进入零重力模式",
"副驾驶进入巡航沙发模式",
"副驾驶进入休闲躺椅模式",
"副驾驶进入小憩模式",
"副驾驶进入轻松进出模式",
"副驾驶进入宝宝午睡模式",
"副驾驶进入办公模式",
"副驾驶进入冥想空间模式",
"副驾驶进入电感沙滩椅",
"副驾驶进入女王副驾模式",
"副驾驶进入小腿解压悬浮模式",
]
with patch.object(self.service.openai, "interpret", return_value=model_output):
for index, utterance in enumerate(utterances):
with self.subTest(utterance=utterance):
result = self.service.process(
utterance,
"openai",
f"conv-reference-mode-{index}",
vehicle_id="denza_n7",
)
self.assertEqual(result["status"], "succeeded")
self.assertTrue(result["matched_modes"])
self.assertTrue(
result["function_config"] or result["function_configs"]
)
def test_save_recent_successful_actions_as_long_term_mode_profile(self) -> None:
self.service.mode_profiles = ModeProfileRegistry(
self.service.artifact_root / "modes"
)
model_output = {
"detected_domains": ["roof"],
"requests": [
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "transmittance_pct", "value": 35}],
"reason": "保存前先形成一个可复用动作。",
}
],
"ambiguities": [],
"decision_summary": ["天幕透光率设为35%。"],
"confidence": 0.96,
}
with patch.object(self.service.openai, "interpret", return_value=model_output):
first = self.service.process(
"天幕透光率调到35%",
"openai",
"conv-save-mode-profile",
vehicle_id="denza_n7",
)
saved = self.service.process(
"这个模式不错,固化为露营模式",
"local",
"conv-save-mode-profile",
vehicle_id="denza_n7",
)
self.assertEqual(first["status"], "succeeded")
self.assertEqual(saved["status"], "succeeded")
self.assertIsNone(saved["command_plan"])
self.assertEqual(saved["mode_profile"]["name"], "露营模式")
telemetry = saved["execution_report"]["spec"]["results"][0]["telemetry"]
self.assertEqual(telemetry["operation"], "save_mode_profile")
self.assertFalse(telemetry["can_command_emitted"])
registry = ModeProfileRegistry(self.service.artifact_root / "modes")
matched = registry.match_text("进入露营模式", vehicle_id="denza_n7")
requests = registry.requests_for_profiles(matched)
self.assertEqual(requests[0]["capability"], "roof.set_transmittance")
self.assertEqual(
requests[0]["parameters"],
[{"name": "transmittance_pct", "value": 35}],
)
self.assertEqual(
registry.match_text("进入露营模式", vehicle_id="other_vehicle"),
[],
)
def test_update_and_restore_long_term_mode_profile_are_control_plane_only(self) -> None:
self.service.mode_profiles = ModeProfileRegistry(
self.service.artifact_root / "modes"
)
profile = self.service.mode_profiles.save_mode(
"露营模式",
[
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": {"transmittance_pct": 20},
"reason": "原始天幕目标。",
}
],
vehicle_id="denza_n7",
)
model_output = {
"detected_domains": ["roof"],
"requests": [
{
"domain": "roof",
"capability": "roof.set_transmittance",
"target_scope": "vehicle",
"operation": "set",
"parameters": [{"name": "transmittance_pct", "value": 50}],
"reason": "用户修改长期模式天幕目标。",
}
],
"ambiguities": [],
"decision_summary": ["修改露营模式天幕目标。"],
"confidence": 0.96,
}
with patch.object(self.service.openai, "interpret", return_value=model_output):
updated = self.service.process(
"修改露营模式,天幕透光率改到50%",
"openai",
"conv-update-mode-profile",
execution_mode="hardware",
vehicle_id="denza_n7",
)
self.assertEqual(updated["status"], "succeeded")
self.assertIsNone(updated["command_plan"])
update_telemetry = updated["execution_report"]["spec"]["results"][0][
"telemetry"
]
self.assertEqual(update_telemetry["operation"], "update_mode_profile")
self.assertFalse(update_telemetry["can_command_emitted"])
self.assertTrue(Path(profile.source).with_suffix(".yaml.initial.bak").is_file())
registry = ModeProfileRegistry(self.service.artifact_root / "modes")
requests = registry.requests_for_profiles(
registry.match_text("进入露营模式", vehicle_id="denza_n7")
)
self.assertEqual(
requests[0]["parameters"],
[{"name": "transmittance_pct", "value": 50}],
)
restored = self.service.process(
"恢复露营模式初始配置",
"local",
"conv-update-mode-profile",
execution_mode="hardware",
vehicle_id="denza_n7",
)
self.assertEqual(restored["status"], "succeeded")
self.assertIsNone(restored["command_plan"])
restore_telemetry = restored["execution_report"]["spec"]["results"][0][
"telemetry"
]
self.assertEqual(restore_telemetry["operation"], "restore_mode_profile")
self.assertFalse(restore_telemetry["can_command_emitted"])
restored_registry = ModeProfileRegistry(self.service.artifact_root / "modes")
restored_requests = restored_registry.requests_for_profiles(
restored_registry.match_text("进入露营模式", vehicle_id="denza_n7")
)
self.assertEqual(
restored_requests[0]["parameters"],
[{"name": "transmittance_pct", "value": 20}],
)
if __name__ == "__main__":
unittest.main()