105 lines
2.9 KiB
Python
105 lines
2.9 KiB
Python
import json
|
|
import unittest
|
|
|
|
from cockpit_agent.intent.parser import ModelIntentParser
|
|
|
|
|
|
EXPECTED = {
|
|
"主驾23度": {
|
|
"domain": "climate",
|
|
"function": "temperature",
|
|
"zone": "driver",
|
|
"operation": "set",
|
|
"state": None,
|
|
"value": 23,
|
|
"unit": "celsius",
|
|
},
|
|
"把驾驶位温度调成23℃": {
|
|
"domain": "climate",
|
|
"function": "temperature",
|
|
"zone": "driver",
|
|
"operation": "set",
|
|
"state": None,
|
|
"value": 23,
|
|
"unit": "celsius",
|
|
},
|
|
"副驾温度降低2度": {
|
|
"domain": "climate",
|
|
"function": "temperature",
|
|
"zone": "passenger",
|
|
"operation": "decrease",
|
|
"state": None,
|
|
"value": 2,
|
|
"unit": "celsius",
|
|
},
|
|
"打开内循环": {
|
|
"domain": "climate",
|
|
"function": "air_recirculation",
|
|
"zone": "all",
|
|
"operation": "set",
|
|
"state": "on",
|
|
"value": None,
|
|
"unit": None,
|
|
},
|
|
"关闭主驾空调": {
|
|
"domain": "climate",
|
|
"function": "climate_power",
|
|
"zone": "driver",
|
|
"operation": "set",
|
|
"state": "off",
|
|
"value": None,
|
|
"unit": None,
|
|
},
|
|
"后备箱最大开度80%": {
|
|
"domain": "body",
|
|
"function": "tailgate_max_opening",
|
|
"zone": None,
|
|
"operation": "set",
|
|
"state": None,
|
|
"value": 80,
|
|
"unit": "percent",
|
|
},
|
|
"解锁全部车门": {
|
|
"domain": "body",
|
|
"function": "unlock_mode",
|
|
"zone": None,
|
|
"operation": "set",
|
|
"state": None,
|
|
"value": "all_doors",
|
|
"unit": None,
|
|
},
|
|
}
|
|
|
|
|
|
class FakeTextGenerator:
|
|
def generate_text(self, prompt: str, max_new_tokens: int = 256) -> str:
|
|
del max_new_tokens
|
|
instruction = prompt.rsplit("用户指令:", maxsplit=1)[1].strip()
|
|
return "```json\n" + json.dumps(EXPECTED[instruction]) + "\n```"
|
|
|
|
|
|
class IntentParserTest(unittest.TestCase):
|
|
def test_required_instruction_variants(self) -> None:
|
|
parser = ModelIntentParser(FakeTextGenerator())
|
|
for instruction, expected in EXPECTED.items():
|
|
with self.subTest(instruction=instruction):
|
|
self.assertEqual(parser.parse(instruction).to_dict(), expected)
|
|
|
|
def test_empty_instruction_is_rejected(self) -> None:
|
|
parser = ModelIntentParser(FakeTextGenerator())
|
|
with self.assertRaisesRegex(ValueError, "non-empty"):
|
|
parser.parse(" ")
|
|
|
|
def test_invalid_model_schema_is_rejected(self) -> None:
|
|
class InvalidGenerator:
|
|
def generate_text(self, prompt: str, max_new_tokens: int = 256) -> str:
|
|
del prompt, max_new_tokens
|
|
return '{"domain": "climate"}'
|
|
|
|
with self.assertRaisesRegex(ValueError, "missing fields"):
|
|
ModelIntentParser(InvalidGenerator()).parse("打开内循环")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|