fix: restore mode clicks and compose seat-aware assistant scenes

This commit is contained in:
vee
2026-09-12 13:33:38 +08:00
parent 76057be044
commit d09b5967f8
28 changed files with 1247 additions and 44 deletions
+48 -2
View File
@@ -71,6 +71,28 @@ _SEAT_UNSUPPORTED_SCOPE = re.compile(
r"左后|右后|前舱|后舱|左侧|右侧|左边|右边|"
r"所有座椅|全部座椅|全车座椅"
)
_SCENE_NON_SEAT_SCOPED_DEVICE = re.compile(
rf"(?:{_SEAT_DRIVER_SCOPE.pattern}|{_SEAT_PASSENGER_SCOPE.pattern}|"
rf"{_SEAT_UNSUPPORTED_SCOPE.pattern})\s*(?:的)?\s*"
r"(?=空调|温度|风量|出风|风口|除霜|车窗|窗户|车门|门锁|"
r"阅读灯|氛围灯|灯光|遮阳帘|天幕)",
re.IGNORECASE,
)
def resolve_scene_seat_scopes(utterance: str) -> frozenset[str] | None:
"""Keep a scene's explicit seat scope without borrowing an HVAC/light zone.
A name such as 主驾舒适模式 still constrains seat actions even when it
omits 座椅. But 副驾空调与座椅舒适模式 does not authorize restricting
every seat action to the passenger. Only remove scope tokens directly
attached to another device; all negation text remains untouched.
"""
scoped_text = _SCENE_NON_SEAT_SCOPED_DEVICE.sub(
"", utterance.replace("主副驾", "主驾和副驾")
)
return resolve_explicit_seat_scopes(scoped_text, assume_seat_context=True)
def resolve_explicit_seat_scopes(
@@ -356,7 +378,13 @@ def _remove_conflicting_controls(
result[field] = kept
def apply_language_safety_guards(parsed: dict[str, Any], utterance: str) -> dict[str, Any]:
def apply_language_safety_guards(
parsed: dict[str, Any],
utterance: str,
*,
scene_composition: bool = False,
scene_scope_utterance: str | None = None,
) -> dict[str, Any]:
"""Preserve negation and unresolved control language without producing CAN."""
result = deepcopy(parsed)
@@ -386,7 +414,25 @@ def apply_language_safety_guards(parsed: dict[str, Any], utterance: str) -> dict
]
result["confidence"] = min(float(result.get("confidence", 0)), 0.8)
explicit_seat_scopes = resolve_explicit_seat_scopes(utterance)
explicit_seat_scopes = (
resolve_scene_seat_scopes(
utterance if scene_scope_utterance is None else scene_scope_utterance
)
if scene_composition
else resolve_explicit_seat_scopes(utterance)
)
if scene_composition and not any(
isinstance(item, dict)
and (
item.get("domain") == "seat"
or str(item.get("capability", "")).startswith("seat.")
)
for key in _EXECUTION_LIST_FIELDS
for item in result.get(key, [])
):
# A rear-window ventilation scene is not a rear-seat request. The
# scene guard already checks every seat candidate before adaptation.
explicit_seat_scopes = None
if explicit_seat_scopes is not None:
removed = _filter_explicit_seat_scope(result, explicit_seat_scopes)
if removed: