"""Deterministic routing hints for background voice tasks.""" from __future__ import annotations import re # Gemma is a small model and will sometimes promise to do work without actually # calling dispatch_task. Force that tool for high-confidence background intents; # the main prompt remains responsible for less obvious cases. _BACKGROUND_TASK_RE = re.compile( r"\b(?:" r"latest|news|current events?|headlines?|prices?|scores?|" r"research|look\s+up|search(?:\s+for)?|find\s+out|investigate|" r"compare|comparison|pros\s+and\s+cons|" r"plan|itinerary|schedule|" r"write|draft|compose|rewrite|" r"summari[sz]e|summary|analy[sz]e|analysis|review|report|" r"recommend|recommendation|options?|developments?" r")\b", re.IGNORECASE, ) _MEMORY_INTENT_RE = re.compile( r"\b(?:remember|memory|memories|forget|write down|my name|" r"what do you know about me|preference|preferences)\b", re.IGNORECASE, ) _DIRECT_WEATHER_TIME_RE = re.compile( r"\b(?:weather|temperature|forecast|what time|current time|what day|today's date)\b", re.IGNORECASE, ) def should_force_background_task(text: str) -> bool: """Return whether a fresh user turn should be forced through dispatch_task. This deliberately favors precise intent signals over trying to classify every possible request. Memory stays on its authenticated MCP and straightforward weather/time requests stay on their purpose-built tools. """ normalized = " ".join((text or "").split()) if not normalized or _MEMORY_INTENT_RE.search(normalized): return False if re.search(r"\b(?:my|saved)\s+notes?\b", normalized, re.IGNORECASE): return False match = _BACKGROUND_TASK_RE.search(normalized) if not match: return bool(re.search(r"\b(?:tell me about|give me an overview of)\b", normalized, re.I)) # Straightforward weather/time requests stay on the fast dedicated MCP. # Comparisons, research, plans, and written reports still go background. if _DIRECT_WEATHER_TIME_RE.search(normalized) and not re.search( r"\b(?:compare|comparison|research|investigate|plan|write|draft|" r"summari[sz]e|analy[sz]e|review|report)\b", normalized, re.IGNORECASE, ): return False return True