@@ -99,26 +99,28 @@ def should_handle(self, text: str) -> bool:
9999 text_clean = text .strip ()
100100 text_lower = text .lower ().strip ()
101101
102+ area_names , device_types = self ._parse_device_and_area (text_lower , global_config )
103+ target_entities = self ._match_named_entities (text_lower , device_types or None , area_names )
104+
102105 # 规则1: 检查明确的全局关键词 - HA不支持的功能
103106 global_keywords = global_config .get ('global_keywords' , [])
104107 has_global_keyword = any (keyword in text_lower for keyword in global_keywords )
105108
106109 # 规则2: 检查显式动作/参数指令
107110 has_action_word = self ._has_explicit_action_word (text_lower , global_config )
108111 has_parameter_command = self ._has_parameter_command (text , text_lower , global_config )
109- has_target_hint = self . _has_target_hint ( text_lower , global_config )
112+ has_resolved_target = bool ( device_types or target_entities )
110113 is_short_text = len (text_clean ) <= 4
111114
112- # 关键判断:
113- # 1. 全局控制直接本地处理
114- # 2. 显式参数控制 + 明确目标,本地处理以补足中文能力
115- # 3. 显式开关控制 + 明确目标,本地处理以补足中文泛化开关
116- should_handle = has_global_keyword or (
117- has_target_hint and (has_action_word or has_parameter_command )
118- )
115+ # 本地增强意图必须完整命中可执行控制目标,不能靠模糊猜测。
116+ should_handle = has_resolved_target and (has_action_word or has_parameter_command )
119117
120- # 对于有动作词的短文本,如果缺少全局关键词,则不处理
121- if has_action_word and is_short_text and not has_global_keyword and not has_target_hint :
118+ # 全局控制也必须解析出具体设备类型,避免“打开所有”之类半句被错误接管。
119+ if has_global_keyword and not device_types and not target_entities :
120+ should_handle = False
121+
122+ # 对于短文本,如果没有完整命中目标,则不处理。
123+ if (has_action_word or has_parameter_command ) and is_short_text and not has_resolved_target :
122124 should_handle = False
123125
124126 _LOGGER .debug ("Local intent check: '%s' -> %s" , text , should_handle )
@@ -203,14 +205,6 @@ def _has_explicit_action(
203205
204206 return any (action in text_without_state for action in action_words )
205207
206- def _has_target_hint (self , text_lower : str , global_config : dict ) -> bool :
207- """Check whether the text contains a concrete area/device hint."""
208- area_names , device_types = self ._parse_device_and_area (text_lower , global_config )
209- if area_names or device_types :
210- return True
211-
212- return bool (self ._match_named_entities (text_lower ))
213-
214208 def _parse_device_and_area (self , text_lower : str , global_config : dict ) -> tuple :
215209 """解析设备类型和区域."""
216210 area_names = []
@@ -399,7 +393,17 @@ async def _execute_control(
399393 fail_msg = fail_msg ,
400394 )
401395
402- return self ._create_response (language , message )
396+ success_results = [
397+ {
398+ "type" : "entity" ,
399+ "name" : self ._get_device_friendly_name (device_id ),
400+ "id" : device_id ,
401+ }
402+ for device_id in all_devices
403+ if self .hass .states .get (device_id ) is not None
404+ ]
405+
406+ return self ._create_response (language , message , success_results = success_results )
403407
404408 except Exception as e :
405409 message = self ._format_response_message ('error' , error = str (e ))
@@ -506,9 +510,20 @@ def _format_failure_message(self, error_count: int, failed_devices: list) -> str
506510 template = failure_config .get ('many_devices' , '' )
507511 return template .format (error_count = len (unique_failed ), failed_list = failed_list )
508512
509- def _create_response (self , language : str , message : str , is_error : bool = False ):
513+ def _create_response (
514+ self ,
515+ language : str ,
516+ message : str ,
517+ is_error : bool = False ,
518+ success_results : list [dict [str , Any ]] | None = None ,
519+ ):
510520 """创建响应结果."""
511- return create_intent_result (language , message , is_error = is_error )
521+ return create_intent_result (
522+ language ,
523+ message ,
524+ is_error = is_error ,
525+ success_results = success_results ,
526+ )
512527
513528 # ========== 参数控制方法 ==========
514529
0 commit comments