import re import sys import json def calculate_ambiguity_score(user_request, context={}): score = 0 factors = [] # Factor 1: No file path (higher ambiguity) file_path_pattern = r'(\/[\w.-]+\/[\w.-]+)|([A-Z]:\\[\w.-]+\\[\w.-]+)|(\.\/[\w.-]+)|(\.(js|ts|py|go|rs|java|tsx|jsx|vue|svelte|md|json|yaml|yml)$)' if not re.search(file_path_pattern, user_request, re.IGNORECASE): factors.append('no_file_path') score += 0.15 # Factor 2: No technical terms tech_terms = [ 'api', 'database', 'server', 'client', 'component', 'module', 'function', 'class', 'interface', 'type', 'schema', 'endpoint', 'authentication', 'authorization', 'middleware', 'controller', 'service', 'repository', 'model', 'view', 'hook', 'context' ] if not any(term in user_request.lower() for term in tech_terms): factors.append('no_technical_terms') score += 0.1 # Factor 3: No specific nouns (PascalCase or camelCase) if not re.search(r'("[^"]+")|(\'[^\']+\')|([A-Z][a-z]+[A-Z][a-z]+)|([a-z]+[A-Z][a-z]+)', user_request): factors.append('no_specific_nouns') score += 0.15 # Factor 4: No scope definition scope_patterns = [ r'only|just|specifically|exactly', r'all|every|entire|whole', r'from\s+\w+\s+to\s+\w+', r'in\s+the\s+\w+\s+(?:file|folder|directory|module)' ] if not any(re.search(p, user_request, re.IGNORECASE) for p in scope_patterns): factors.append('no_scope') score += 0.1 # Factor 5: Multiple interpretations ambiguous_patterns = [ r'maybe|perhaps|or|either', r'it|this|that|those|these', r'stuff|things|something', r'fix|update|change|modify' ] pronoun_count = len(re.findall(r'\b(it|this|that)\b', user_request, re.IGNORECASE)) if pronoun_count >= 2 or any(re.search(p, user_request, re.IGNORECASE) for p in ambiguous_patterns): factors.append('multiple_interpretations') score += 0.2 # Factor 6: Short request if len(user_request) < 30: factors.append('short_request') score += 0.15 # Factor 7: Context Conflict (New in v2) # Check if request contradicts current phase current_phase = context.get('current_feature_phase', 'PLAN') phase_keywords = { 'PLAN': ['implement', 'code', 'build', 'deploy'], 'DESIGN': ['deploy', 'test', 'release'], 'DO': ['plan', 'design', 'architecture'] } conflict_keywords = phase_keywords.get(current_phase, []) for keyword in conflict_keywords: if keyword in user_request.lower(): factors.append(f'context_conflict_with_{current_phase}') score += 0.15 break score = min(1.0, max(0.0, score)) return {"score": score, "factors": factors} if __name__ == "__main__": if len(sys.argv) < 2: print(json.dumps({"error": "No request provided"})) sys.exit(1) request = sys.argv[1] # Simulate context from arg 2 if present context = {} if len(sys.argv) > 2: try: context = json.loads(sys.argv[2]) except: pass result = calculate_ambiguity_score(request, context) print(json.dumps(result, indent=2))