feat: integrate safer vehicle CAN reasoning

This commit is contained in:
vee
2026-08-12 22:50:55 +08:00
parent 9ce64b3a01
commit fd3c219c39
15 changed files with 1768 additions and 30 deletions
+123
View File
@@ -0,0 +1,123 @@
from __future__ import annotations
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from cognitive_agent.application.native_can_relative import NativeCanRelativeResolver
from cognitive_agent.application.seat_service import REPOSITORY_ROOT, SeatDemoService
class CanTestBranchFusionTests(unittest.TestCase):
def setUp(self) -> None:
self.service = SeatDemoService(REPOSITORY_ROOT)
self.temporary_directory = tempfile.TemporaryDirectory()
self.addCleanup(self.temporary_directory.cleanup)
self.service.artifact_root = Path(self.temporary_directory.name)
def test_negated_vehicle_control_never_compiles_or_executes(self) -> None:
result = self.service.process(
"不要打开左前车窗",
provider="local",
conversation_id="conv-negative-window",
)
self.assertEqual(result["status"], "no_action")
spec = result["intent_ir"]["spec"]
self.assertEqual(spec["actions"], [])
self.assertEqual(spec["constraints"][0]["capability"], "window.set_motion")
self.assertFalse(spec["execution_eligible"])
self.assertEqual(result["function_configs"], {})
def test_multiple_windows_and_exclusion_are_deterministic(self) -> None:
multiple = self.service.process(
"打开左前和右前车窗",
provider="local",
conversation_id="conv-two-windows",
)
self.assertEqual(multiple["status"], "succeeded")
self.assertEqual(
[item["target"]["zone"] for item in multiple["intent_ir"]["spec"]["actions"]],
["front_left", "front_right"],
)
excluded = self.service.process(
"打开全部车窗,左前除外",
provider="local",
conversation_id="conv-excluded-window",
)
self.assertEqual(excluded["status"], "succeeded")
self.assertEqual(
[item["target"]["zone"] for item in excluded["intent_ir"]["spec"]["actions"]],
["front_right", "rear_left", "rear_right"],
)
self.assertEqual(
excluded["intent_ir"]["spec"]["constraints"][0]["type"],
"exclude_target",
)
def test_unresolved_mixed_control_fails_closed_before_compile(self) -> None:
result = self.service.process(
"打开左前车窗,再把座椅调舒服点",
provider="local",
conversation_id="conv-unresolved-mixed",
)
self.assertEqual(result["status"], "needs_confirmation")
self.assertFalse(result["intent_ir"]["spec"]["execution_eligible"])
self.assertEqual(result["function_configs"], {})
self.assertIn(
"UNRESOLVED_UTTERANCE_SPAN",
{item["code"] for item in result["validation"]},
)
def test_relative_fan_uses_current_state_and_records_resolution(self) -> None:
result = self.service.process(
"把风量提高两档",
provider="local",
conversation_id="conv-relative-fan",
)
self.assertEqual(result["status"], "succeeded")
action = result["intent_ir"]["spec"]["actions"][0]
self.assertEqual(action["capability"], "climate.set_fan_level")
self.assertEqual(action["parameters"], {"level": 2})
self.assertEqual(action["resolution"]["current"], 0)
self.assertEqual(action["resolution"]["delta"], 2)
def test_relative_vehicle_control_requires_physical_feedback_in_hardware_context(self) -> None:
resolver = NativeCanRelativeResolver(REPOSITORY_ROOT)
context = self.service.conversations.snapshot("conv-relative-physical")
context["domain_devices"]["vehicle_status"]["feedback_source"] = "physical_can_ch1"
result = resolver.resolve("把风量提高一档", context)
self.assertEqual(result.actions, [])
self.assertEqual(
result.ambiguities[0]["reason"],
"native_can_relative_state_not_physical",
)
def test_reasoning_effort_reaches_openai_payload(self) -> None:
self.service.openai.api_key = "test-key"
plan = {
"detected_domains": ["window"],
"requests": [],
"ambiguities": [],
"decision_summary": ["no action"],
"confidence": 0.9,
}
with patch.object(self.service.openai, "interpret", return_value=plan) as interpret:
self.service.process(
"你好",
provider="openai",
conversation_id="conv-reasoning-effort",
reasoning_effort="high",
)
self.assertEqual(interpret.call_args.kwargs["reasoning_effort"], "high")
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,31 @@
from __future__ import annotations
from pathlib import Path
import unittest
REPOSITORY_ROOT = Path(__file__).resolve().parents[2]
CONSOLE_SOURCE = REPOSITORY_ROOT / "apps" / "web-console" / "console-v2.js"
CONSOLE_STYLES = REPOSITORY_ROOT / "apps" / "web-console" / "console-v2.css"
class FrontendReasoningLayoutContractTests(unittest.TestCase):
def test_reasoning_control_is_removed_from_fixed_height_request_form(self) -> None:
source = CONSOLE_SOURCE.read_text(encoding="utf-8")
self.assertIn('const reasoningField = $("#reasoningField", originalForm);', source)
self.assertIn('reasoningField.classList.add("v2-reasoning-field");', source)
self.assertIn("composer.append(trigger);", source)
self.assertIn("document.body.append(reasoningField);", source)
self.assertIn('trigger.setAttribute("aria-haspopup", "listbox");', source)
def test_v2_reasoning_control_has_compact_bounded_layout(self) -> None:
styles = CONSOLE_STYLES.read_text(encoding="utf-8")
self.assertIn(".console-v2 .v2-reasoning-field .reasoning-segmented", styles)
self.assertIn(".console-v2 .v2-reasoning-trigger", styles)
self.assertIn("position: fixed;", styles)
self.assertIn("min-height: 42px;", styles)
self.assertIn("white-space: nowrap;", styles)
if __name__ == "__main__":
unittest.main()