Skip to content

Commit 670dda1

Browse files
committed
fix: preserve LLM chat context after HA intent fallback
1 parent 43a4494 commit 670dda1

2 files changed

Lines changed: 35 additions & 42 deletions

File tree

custom_components/ai_hub/conversation.py

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -138,50 +138,43 @@ async def _async_handle_message(
138138
# ========== 步骤2: 尝试 HA 内置意图处理 ==========
139139
# timer、shopping list、设备控制等 HA 原生支持的意图
140140
try:
141-
from homeassistant.components.conversation import default_agent
141+
from homeassistant.components import conversation as ha_conversation
142142

143-
# 获取 HA 默认的 conversation agent
144-
# HA 2025.10+ 使用 async_get_agent
145-
agent = getattr(default_agent, 'async_get_agent', None)
146-
if agent:
147-
agent = await agent(self.hass)
148-
else:
149-
# 降级方案:直接使用 default_agent 模块的 process 函数
150-
agent = default_agent
151-
152-
if agent:
153-
_LOGGER.debug("调用 HA 默认 agent 处理: %s", user_input.text)
154-
# 让默认 agent 处理
155-
result = await agent.async_process(user_input)
156-
_LOGGER.debug("HA agent 返回结果: %s", result)
157-
if result and result.response:
158-
response_type = result.response.response_type
159-
_LOGGER.debug("HA agent response_type: %s", response_type)
160-
161-
# 检查是否有错误
162-
has_error = hasattr(result.response, 'error') and result.response.error
163-
# 检查是否是 "no intent matched" 情况
164-
is_no_match = (response_type == intent.IntentResponseType.NO_INTENT_MATCHED
165-
if hasattr(intent.IntentResponseType, 'NO_INTENT_MATCHED') else False)
166-
167-
# 只要有响应内容就认为成功(不管是什么类型)
168-
# 除非明确是 NO_INTENT_MATCHED 或有错误
169-
response_has_content = (
170-
hasattr(result.response, 'speech') and result.response.speech.get('plain')
171-
) or (
172-
hasattr(result.response, 'response_type')
143+
_LOGGER.debug("调用 HA 内置 intents 处理: %s", user_input.text)
144+
ha_response = await ha_conversation.async_handle_intents(
145+
self.hass,
146+
user_input,
147+
chat_log,
148+
)
149+
150+
_LOGGER.debug("HA intents 返回结果: %s", ha_response)
151+
152+
if ha_response is not None:
153+
response_type = ha_response.response_type
154+
_LOGGER.debug("HA intents response_type: %s", response_type)
155+
156+
has_error = hasattr(ha_response, "error") and ha_response.error
157+
is_error_type = response_type == intent.IntentResponseType.ERROR
158+
is_no_match = (
159+
response_type == intent.IntentResponseType.NO_INTENT_MATCHED
160+
if hasattr(intent.IntentResponseType, "NO_INTENT_MATCHED")
161+
else False
162+
)
163+
response_has_content = bool(ha_response.speech and ha_response.speech.get("plain"))
164+
165+
if not has_error and not is_error_type and not is_no_match and response_has_content:
166+
_LOGGER.info("HA 内置意图处理成功: %s, type: %s", user_input.text, response_type)
167+
return conversation.ConversationResult(
168+
response=ha_response,
169+
conversation_id=chat_log.conversation_id,
173170
)
174171

175-
if not has_error and not is_no_match and response_has_content:
176-
_LOGGER.info("HA 内置意图处理成功: %s, type: %s", user_input.text, response_type)
177-
return result
178-
else:
179-
_LOGGER.debug(
180-
"HA 内置意图未匹配(has_error=%s, is_no_match=%s),交给 LLM 处理",
181-
has_error, is_no_match
182-
)
183-
else:
184-
_LOGGER.warning("HA 默认 agent 不可用")
172+
_LOGGER.debug(
173+
"HA 内置意图未匹配或返回错误(has_error=%s, is_error_type=%s, is_no_match=%s),交给 LLM 处理",
174+
has_error,
175+
is_error_type,
176+
is_no_match,
177+
)
185178

186179
except Exception as e:
187180
_LOGGER.warning("HA 内置意图处理异常: %s", e, exc_info=True)

custom_components/ai_hub/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
"iot_class": "cloud_polling",
1010
"issue_tracker": "https://github.com/ha-china/ai_hub/issues",
1111
"requirements": ["edge-tts==7.2.7", "aiofiles", "aiohttp"],
12-
"version": "v2026.3.1"
12+
"version": "v2026.3.2"
1313
}

0 commit comments

Comments
 (0)