115 lines
3.9 KiB
Python
115 lines
3.9 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from cognitive_agent.infrastructure.speech.understanding import (
|
|
UnderstandingTranscriptProcessor,
|
|
)
|
|
|
|
REPOSITORY_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def processor() -> UnderstandingTranscriptProcessor:
|
|
return UnderstandingTranscriptProcessor(REPOSITORY_ROOT)
|
|
|
|
|
|
def test_preview_only_request_preserves_duration_and_governing_connector(
|
|
processor: UnderstandingTranscriptProcessor,
|
|
) -> None:
|
|
result = processor.process(
|
|
"主驾座椅靠背向后移动3s,先不要下发,给出解析的控制指令"
|
|
)
|
|
|
|
assert result.assistant_text == (
|
|
"将主驾座椅靠背向后移动3秒,先不要下发,给出解析的控制指令。"
|
|
)
|
|
assert result.clean_text == "将主驾座椅靠背向后移动3秒。"
|
|
assert len(result.commands) == 1
|
|
command = result.commands[0]
|
|
assert command.capability == "seat.set_driver_axis_native"
|
|
assert command.parameters == {
|
|
"axis": "backrest",
|
|
"direction": "backward",
|
|
"duration_ms": 3000,
|
|
}
|
|
assert "angle_delta_deg" not in command.parameters
|
|
assert command.resolution_status == "unsupported"
|
|
assert any("工程上限2000" in issue for issue in command.validation_issues)
|
|
assert not result.execution_eligible
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("spoken", "duration_ms", "display"),
|
|
(
|
|
("2s", 2000, "2秒"),
|
|
("1.5秒", 1500, "1.5秒"),
|
|
("300ms", 300, "300毫秒"),
|
|
("300毫秒", 300, "300毫秒"),
|
|
("一秒", 1000, "1秒"),
|
|
("两秒", 2000, "2秒"),
|
|
("半秒", 500, "500毫秒"),
|
|
("一点五秒", 1500, "1.5秒"),
|
|
),
|
|
)
|
|
def test_explicit_duration_units_remain_explicit_in_structured_and_display_text(
|
|
processor: UnderstandingTranscriptProcessor,
|
|
spoken: str,
|
|
duration_ms: int,
|
|
display: str,
|
|
) -> None:
|
|
result = processor.process(f"主驾椅背向后移动{spoken}")
|
|
|
|
assert result.commands[0].parameters["duration_ms"] == duration_ms
|
|
assert "duration_ms" not in result.commands[0].qualifiers.get(
|
|
"implicit_parameters", ()
|
|
)
|
|
assert display in result.clean_text
|
|
assert display in result.assistant_text
|
|
assert "angle_delta_deg" not in result.commands[0].parameters
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("spoken", "duration_ms"),
|
|
(("3s", 3000), ("三秒", 3000), ("1分钟", 60_000)),
|
|
)
|
|
def test_out_of_range_time_stays_a_duration_and_fails_closed(
|
|
processor: UnderstandingTranscriptProcessor,
|
|
spoken: str,
|
|
duration_ms: int,
|
|
) -> None:
|
|
result = processor.process(f"主驾座椅靠背向后移动{spoken}")
|
|
|
|
command = result.commands[0]
|
|
assert command.capability == "seat.set_driver_axis_native"
|
|
assert command.parameters["duration_ms"] == duration_ms
|
|
assert "angle_delta_deg" not in command.parameters
|
|
assert command.resolution_status == "unsupported"
|
|
assert not result.execution_eligible
|
|
|
|
|
|
def test_time_unit_is_not_reinterpreted_as_passenger_backrest_angle(
|
|
processor: UnderstandingTranscriptProcessor,
|
|
) -> None:
|
|
result = processor.process("副驾座椅靠背向后移动3s")
|
|
|
|
assert result.assistant_text == "副驾座椅靠背向后移动3s。"
|
|
assert result.commands[0].parameters == {}
|
|
assert result.commands[0].resolution_status == "incomplete"
|
|
assert "seat_timed_motion_not_registered_for_scope" in result.reasons
|
|
assert not result.execution_eligible
|
|
|
|
|
|
def test_default_driver_axis_duration_remains_implicit(
|
|
processor: UnderstandingTranscriptProcessor,
|
|
) -> None:
|
|
result = processor.process("主驾座椅靠背向后移动")
|
|
|
|
command = result.commands[0]
|
|
assert command.parameters["duration_ms"] == 500
|
|
assert "duration_ms" in command.qualifiers["implicit_parameters"]
|
|
assert "500" not in result.assistant_text
|
|
assert result.assistant_text == "将主驾座椅靠背向后调整。"
|