#!/usr/bin/env python3 """ Chat Intent Parser - Determine what type of query the user is making """ import re from typing import Dict, Tuple class ChatIntentParser: """Parse user queries to determine intent and scope""" # Patterns for different intents PATTERNS = { 'kg_search': { 'patterns': [ r'(search|find|look for|show me).*in.*knowledge|what.*entity|find.*entity', r'(entity|concept|topic).*named?', ], 'keywords': ['entity', 'concept', 'topic', 'knowledge', 'search'] }, 'project_info': { 'patterns': [ r'(project|projects).*info|tell.*project', r'what.*project|list.*project|show.*project', ], 'keywords': ['project', 'projects'] }, 'system_status': { 'patterns': [ r'(system|status|health|running|services)', r'(disk|memory|cpu|load|uptime)', r'(docker|container|process)', ], 'keywords': ['system', 'status', 'health', 'disk', 'memory', 'running'] }, 'architecture': { 'patterns': [ r'(architecture|structure|how.*work|design)', r'(component|module|service).*architecture', ], 'keywords': ['architecture', 'structure', 'design', 'component'] }, 'help': { 'patterns': [ r'(help|what can|commands|available)', r'(how.*use|guide|tutorial)', ], 'keywords': ['help', 'commands', 'guide'] } } def __init__(self): """Initialize parser""" pass def parse(self, query: str) -> Dict: """Parse query and determine intent""" query_lower = query.lower().strip() result = { 'original_query': query, 'query_lower': query_lower, 'intent': 'general', 'confidence': 0.0, 'scope': 'all', 'keywords': self._extract_keywords(query_lower), 'suggestions': [] } # Check for explicit scope flags if query_lower.startswith('--kg ') or ' --kg ' in query_lower: result['scope'] = 'kg' query_lower = query_lower.replace('--kg ', '').replace(' --kg ', '') elif query_lower.startswith('--local ') or ' --local ' in query_lower: result['scope'] = 'local_memory' query_lower = query_lower.replace('--local ', '').replace(' --local ', '') elif query_lower.startswith('--bash ') or ' --bash ' in query_lower: result['scope'] = 'bash' query_lower = query_lower.replace('--bash ', '').replace(' --bash ', '') elif query_lower.startswith('--think ') or ' --think ' in query_lower: result['scope'] = 'reasoning' query_lower = query_lower.replace('--think ', '').replace(' --think ', '') # Detect intent from patterns best_intent = 'general' best_score = 0.0 for intent, config in self.PATTERNS.items(): score = self._calculate_score(query_lower, config) if score > best_score: best_score = score best_intent = intent result['intent'] = best_intent result['confidence'] = min(1.0, best_score) # Generate suggestions result['suggestions'] = self._suggest_queries(best_intent, query_lower) return result def _extract_keywords(self, query: str) -> list: """Extract important keywords from query""" # Simple keyword extraction - words longer than 4 characters words = re.findall(r'\b[a-z_]{4,}\b', query) # Remove common stop words stop_words = {'what', 'that', 'this', 'with', 'from', 'show', 'tell', 'give', 'find'} keywords = [w for w in words if w not in stop_words] return list(set(keywords))[:5] # Return top 5 unique keywords def _calculate_score(self, query: str, config: Dict) -> float: """Calculate how well query matches intent""" score = 0.0 # Check patterns for pattern in config['patterns']: if re.search(pattern, query, re.IGNORECASE): score += 0.4 # Check keywords query_words = set(query.lower().split()) matching_keywords = sum(1 for kw in config['keywords'] if kw in query_words) score += min(0.6, matching_keywords * 0.2) return score def _suggest_queries(self, intent: str, query: str) -> list: """Suggest related queries based on intent""" suggestions = { 'kg_search': [ 'List all research entities', 'Show me recent findings', 'What is stored in the sysadmin domain' ], 'project_info': [ 'List all projects', 'Show project structure', 'What projects are active' ], 'system_status': [ 'Show disk usage', 'List running services', 'What is the system load', 'Show memory usage' ], 'architecture': [ 'Tell me about the system architecture', 'Show me the component structure', 'How do services communicate' ], 'help': [ 'What commands are available', 'Show me examples', 'How do I search the knowledge graph' ] } return suggestions.get(intent, []) def extract_search_term(self, query: str) -> str: """Extract main search term from query""" # Remove common prefixes/suffixes query = re.sub(r'^(show|find|search|list|tell|what|how)\s+', '', query, flags=re.IGNORECASE) query = re.sub(r'\s+(please|thanks|help|info|details)$', '', query, flags=re.IGNORECASE) # Extract quoted terms first quoted = re.findall(r'"([^"]+)"', query) if quoted: return quoted[0] # Otherwise return first significant phrase words = [w for w in query.split() if len(w) > 3] return words[0] if words else query.strip() def is_multi_turn(self, query: str) -> bool: """Check if query suggests multi-turn conversation""" multi_turn_indicators = [ 'more', 'also', 'next', 'then', 'tell me more', 'what else', 'continue', 'go on', 'further' ] query_lower = query.lower() return any(indicator in query_lower for indicator in multi_turn_indicators) if __name__ == '__main__': import json parser = ChatIntentParser() test_queries = [ 'what is the system status', 'find me entities in the KG', 'list all projects', 'tell me about the architecture', '--bash show disk usage', '--think analyze performance patterns' ] for query in test_queries: result = parser.parse(query) print(f"Query: {query}") print(f"Intent: {result['intent']} (confidence: {result['confidence']:.2f})") print(f"Scope: {result['scope']}") print(f"Keywords: {result['keywords']}") print()