|
8 | 8 |
|
9 | 9 | from datetime import datetime, timezone |
10 | 10 | import logging |
| 11 | +import re |
11 | 12 | from typing import Any |
12 | 13 |
|
13 | 14 | from homeassistant.components import conversation |
@@ -201,6 +202,7 @@ async def async_process( |
201 | 202 | return conversation.ConversationResult( |
202 | 203 | response=intent_response, |
203 | 204 | conversation_id=conversation_id, |
| 205 | + continue_conversation=self._should_continue(full_response), |
204 | 206 | ) |
205 | 207 |
|
206 | 208 | def _resolve_conversation_id(self, user_input: conversation.ConversationInput) -> str: |
@@ -315,6 +317,53 @@ def _extract_text_recursive(self, value: Any, depth: int = 0) -> str | None: |
315 | 317 |
|
316 | 318 | return None |
317 | 319 |
|
| 320 | + @staticmethod |
| 321 | + def _should_continue(response: str) -> bool: |
| 322 | + """Determine if the conversation should continue after this response. |
| 323 | +
|
| 324 | + Returns True when the assistant's reply ends with a question or |
| 325 | + an explicit prompt for follow-up, so that Voice PE and other |
| 326 | + satellites automatically re-listen without requiring a wake word. |
| 327 | +
|
| 328 | + The heuristic checks for: |
| 329 | + - Trailing question marks (including after closing quotes/parens) |
| 330 | + - Common conversational follow-up patterns in English and German |
| 331 | + """ |
| 332 | + if not response: |
| 333 | + return False |
| 334 | + |
| 335 | + text = response.strip() |
| 336 | + |
| 337 | + # Check if the response ends with a question mark |
| 338 | + # (allow trailing punctuation like quotes, parens, or emoji) |
| 339 | + if re.search(r"\?\s*[\"'""»)\]]*\s*$", text): |
| 340 | + return True |
| 341 | + |
| 342 | + # Common follow-up patterns (EN + DE) |
| 343 | + lower = text.lower() |
| 344 | + follow_up_patterns = ( |
| 345 | + "what do you think", |
| 346 | + "would you like", |
| 347 | + "do you want", |
| 348 | + "shall i", |
| 349 | + "should i", |
| 350 | + "can i help", |
| 351 | + "anything else", |
| 352 | + "let me know", |
| 353 | + "was meinst du", |
| 354 | + "möchtest du", |
| 355 | + "willst du", |
| 356 | + "soll ich", |
| 357 | + "kann ich", |
| 358 | + "noch etwas", |
| 359 | + "sonst noch", |
| 360 | + ) |
| 361 | + for pattern in follow_up_patterns: |
| 362 | + if pattern in lower: |
| 363 | + return True |
| 364 | + |
| 365 | + return False |
| 366 | + |
318 | 367 | def _error_result( |
319 | 368 | self, |
320 | 369 | user_input: conversation.ConversationInput, |
|
0 commit comments