# ------------------------------------------------------------------------------ # Intent detection patterns # ------------------------------------------------------------------------------ TIME_PATTERNS = [ r"\bwhat(?:'s|\s+is)?\s+(?:the\s+)?time\s*(?:is\s+it|right\s+now|now)?\s*[?.]?\s*$", r"\bwhat(?:'s|\s+is)?\s+(?:the\s+)?time\s+(?:in|for)\s+(?!an?\s+(?:hour|minute|second|moment|sec|min)\b)(?!a\s+while\b)(?!about\b)(?!\d+\b).+", r"\b(?:current|local)\s+time\b", r"\btime\s+(?:right\s+)?now\b", r"^\s*now\??\s*$", r"\bwhat(?:'s|\s+is)?\s+(?:the\s+)?date\b", r"\btoday'?s?\s+date\b", r"\bdate\s+today\b", r"\bwhat\s+day\s+is\s+it\b", r"\bday\s+of\s+week\b", r"\byesterday\b", r"\btime\s+(?:in|for)\s+(?!an?\s+(?:hour|minute|second|moment|sec|min)\b)(?!\d+\b)(.+)", ] def has_time_intent(msg: str) -> bool: m = (msg or "").strip().lower() return any(re.search(p, m, re.IGNORECASE) for p in TIME_PATTERNS) WEATHER_PATTERNS = [ r"\bweather\b", r"\bforecast\b", r"\bwhat(?:'s|\s+is)?\s+(?:the\s+)?weather\b", r"\bweather\s+(?:in|for)\s+.+", r"\bwhat(?:'s|\s+is)?\s+(?:the\s+)?temperature\s*(?:in\b|for\b|\?|$)", r"\btemperature\s+(?:in|for)\s+\S", r"\bhow\s+(?:hot|cold|warm)\s+is\s+it\b", r"\brain(?:ing)?\s+(?:in|for|today|now|outside|tomorrow)\b", r"\b(?:in|for|today|now|outside|tomorrow)\s+rain(?:ing)?\b", r"\bsnow(?:ing)?\b", ] def has_weather_intent(msg: str) -> bool: m = (msg or "").strip().lower() matches = [re.search(p, m, re.IGNORECASE) for p in WEATHER_PATTERNS] if any(matches): if re.search(r"\bsnow(?:ing)?\b", m, re.IGNORECASE): if not re.search(r"\b(in|for|today|tomorrow|now|outside)\b", m, re.IGNORECASE): return False return True return False IMAGE_INTENT_PATTERNS = [ r"\b(generate|create|draw|make)\s+(?:an?\s+)?image\b", r"\bimage\s+of\s+(?!my|your|his|her|our|their|this|that\b)", r"\bpicture\s+of\s+(?!my|your|his|her|our|their|this|that\b)", r"\bgenerate\s+(?:art|illustration|photo|graphic)\b", r"\bdraw\s+me\b", r"\bimagine\s+.+", ] def has_image_intent(msg: str) -> bool: m = (msg or "").strip().lower() if has_generate_video_intent(msg): return False return any(re.search(p, m, re.IGNORECASE) for p in IMAGE_INTENT_PATTERNS) VIDEO_INTENT_PATTERNS = [ r"\byoutube\s+link\b", r"\blink\s+to\s+(?:youtube|video)\b", r"\b(?:give|find|share|play|watch)\s+(?:me\s+)?a\s+(?:youtube|video)\s+link\b", r"\bsong\s+(?:video|link)\b", r"\bmusic\s+video\b", r"\bfunny\s+video\b" ] VIDEO_GEN_KEYWORDS = re.compile( r"\b(animate|generate\s+(?:a\s+)?video|create\s+(?:a\s+)?video|make\s+(?:a\s+)?video)\b", re.IGNORECASE ) def has_video_intent(msg: str) -> bool: m = (msg or "").strip().lower() if VIDEO_GEN_KEYWORDS.search(m): return False return any(re.search(p, m, re.IGNORECASE) for p in VIDEO_INTENT_PATTERNS) EMAIL_PATTERNS = [ r"\bsend\s+(?:an?\s+)?email\b", r"\bping\s+.+@.+\b", r"\bcontact\s+ceo\b" ] def has_email_intent(msg: str) -> bool: m = (msg or "").strip().lower() return any(re.search(p, m, re.IGNORECASE) for p in EMAIL_PATTERNS) NEWS_PATTERNS = [ r"\bnews\b", r"\b(give|tell|what's|what is) (?:me )?(?:the )?news\b", r"\bnews (?:for|in|about) (.+)\b", r"\bheadlines\b", r"\btop stories\b", r"\bcurrent events\b", r"\bbreaking news\b" ] def has_news_intent(msg: str) -> bool: m = (msg or "").strip().lower() return any(re.search(p, m, re.IGNORECASE) for p in NEWS_PATTERNS) ANIMATE_LAST_PATTERNS = [ r"\b(turn|make|convert|transform|animate)\s+(?:the\s+)?(?:last|previous|recent)\s+(?:image|picture|photo)\b", r"\bvideo\s+of\s+(?:the\s+)?last\b", r"\badd\s+motion\s+to\s+last\b" ] def has_animate_last_image_intent(msg: str) -> bool: return any(re.search(p, msg.lower()) for p in ANIMATE_LAST_PATTERNS) # Direct video generation (animate a cat, generate video of X) GENERATE_VIDEO_PATTERNS = [ r"\banimate\s+(?:an?\s+)?(.+)", r"\b(?:generate|create|make)\s+(?:an?\s+)?video\s+(?:of\s+)?(.+)", r"\bvideo\s+of\s+(.+)", ] def has_generate_video_intent(msg: str) -> bool: m = (msg or "").strip().lower() if has_animate_last_image_intent(msg): return False return any(re.search(p, m, re.IGNORECASE) for p in GENERATE_VIDEO_PATTERNS) def extract_video_prompt(msg: str) -> str: """Extract the subject/prompt from a direct video generation request.""" for p in GENERATE_VIDEO_PATTERNS: m = re.search(p, msg.lower(), re.IGNORECASE) if m and m.group(1): prompt = m.group(1).strip() prompt = re.sub(r"[?.!,;:\s]+$", "", prompt) if len(prompt) > 3: return prompt[:300] return msg.strip()[:300] def extract_motion_description(msg: str) -> str: lower = msg.lower() for kw in ["move", "dance", "walk", "run", "fly", "live", "cinematic", "animated"]: if kw in lower: idx = lower.find(kw) tail = msg[idx:].strip() tail = re.sub(r"^(?:the\s+)?(?:last|previous)\s+(?:image|picture)\s*", "", tail, flags=re.I) if len(tail.strip()) > 5: return tail[:150] return "smooth cinematic animation, dynamic motion, high quality" def is_hard_query(msg: str) -> bool: lower_msg = msg.lower().strip() if len(msg) < 50 or has_time_intent(msg) or has_weather_intent(msg) or "joke" in lower_msg or has_image_intent(msg) or has_video_intent(msg) or has_email_intent(msg) or has_news_intent(msg) or lower_msg.startswith(("hi", "hello", "sup", "what is", "who is", "tell me about", "what should i")): return False if any(kw in lower_msg for kw in ["math", "solve", "prove", "code", "program", "puzzle", "explain why", "how does", "think step by step", "analyze", "reason", "multi-step", "complex"]) or len(msg) > 100: return True return False # Help intent HELP_PATTERNS = [r"^help$", r"^what can you do", r"^commands$", r"^capabilities$"] def has_help_intent(msg: str) -> bool: m = (msg or "").strip().lower() return any(re.search(p, m, re.IGNORECASE) for p in HELP_PATTERNS) HELP_TEXT = ( "Here's what I can do:\n" "Images: 'draw me a cat' / 'generate image of a sunset' / 'imagine a dragon'\n" "Video: 'animate a dancing robot' / 'make a video of fireworks' / 'animate the last image'\n" "Weather: 'weather in London' / 'forecast for NYC'\n" "Time: 'what time is it in Tokyo'\n" "News: 'give me the news' / 'news for UK'\n" "YouTube: 'youtube link to Bohemian Rhapsody'\n" "Email: 'send an email to user@example.com'\n" "Clear context: 'clear my context'\n" "Or just chat with me about anything!" )