Spaces:
Running
Running
| """Task detection - analyze requests to determine required capabilities.""" | |
| from __future__ import annotations | |
| import re | |
| from dataclasses import dataclass | |
| from typing import Any | |
| from loguru import logger | |
| from core.anthropic.content import get_block_attr | |
| # Keywords that indicate specific task types | |
| CODING_KEYWORDS = { | |
| "python", | |
| "javascript", | |
| "typescript", | |
| "java", | |
| "c++", | |
| "cpp", | |
| "golang", | |
| "rust", | |
| "ruby", | |
| "php", | |
| "swift", | |
| "kotlin", | |
| "sql", | |
| "html", | |
| "css", | |
| "react", | |
| "vue", | |
| "angular", | |
| "node", | |
| "django", | |
| "flask", | |
| "fastapi", | |
| "spring", | |
| "function", | |
| "class", | |
| "method", | |
| "api", | |
| "endpoint", | |
| "database", | |
| "query", | |
| "algorithm", | |
| "debug", | |
| "error", | |
| "fix", | |
| "implement", | |
| "create", | |
| "write", | |
| "code", | |
| "programming", | |
| "script", | |
| "module", | |
| "import", | |
| "export", | |
| "def ", | |
| "const ", | |
| "let ", | |
| "var ", | |
| "function ", | |
| "async ", | |
| "await ", | |
| } | |
| REASONING_KEYWORDS = { | |
| "analyze", | |
| "analysis", | |
| "reason", | |
| "why", | |
| "how", | |
| "explain", | |
| "compare", | |
| "contrast", | |
| "evaluate", | |
| "assess", | |
| "conclude", | |
| "deduce", | |
| "infer", | |
| "logic", | |
| "proof", | |
| "theorem", | |
| "hypothesis", | |
| "synthesize", | |
| "strategy", | |
| "think", | |
| "solve", | |
| "derive", | |
| "calculate", | |
| "compute", | |
| "math", | |
| "equation", | |
| "formula", | |
| "solution", | |
| "optimal", | |
| "best", | |
| "improve", | |
| "optimize", | |
| "design", | |
| "architecture", | |
| "system", | |
| "plan", | |
| "decision", | |
| "recommend", | |
| } | |
| VISION_KEYWORDS = { | |
| "image", | |
| "picture", | |
| "photo", | |
| "screenshot", | |
| "diagram", | |
| "chart", | |
| "graph", | |
| "visual", | |
| "see", | |
| "look at", | |
| "describe what", | |
| "what's in", | |
| "identify", | |
| "recognize", | |
| "detect", | |
| "object", | |
| "scene", | |
| "face", | |
| "text in image", | |
| } | |
| class TaskRequirements: | |
| """Detected requirements for a request.""" | |
| requires_vision: bool = False | |
| requires_coding: bool = False | |
| requires_reasoning: bool = False | |
| requires_general_text: bool = True | |
| confidence: float = 0.0 # 0-1 confidence in detection | |
| def required_capabilities(self) -> set[str]: | |
| caps = set() | |
| if self.requires_vision: | |
| caps.add("vision") | |
| if self.requires_coding: | |
| caps.add("coding") | |
| if self.requires_reasoning: | |
| caps.add("reasoning") | |
| if self.requires_general_text: | |
| caps.add("general_text") | |
| return caps | |
| class TaskDetector: | |
| """Analyze request messages to detect required capabilities.""" | |
| def detect_requirements(self, messages: list[Any]) -> TaskRequirements: | |
| """Analyze messages and return required capabilities.""" | |
| has_vision = False | |
| has_coding = False | |
| has_reasoning = False | |
| total_text = "" | |
| for msg in messages: | |
| # Handle both dict and object message formats | |
| if isinstance(msg, dict): | |
| content = msg.get("content") | |
| elif hasattr(msg, "content"): | |
| content = msg.content | |
| else: | |
| continue | |
| if isinstance(content, str): | |
| total_text += content.lower() + " " | |
| elif isinstance(content, list): | |
| for block in content: | |
| b_type = get_block_attr(block, "type") or "" | |
| # Check for image content | |
| if b_type == "image": | |
| has_vision = True | |
| logger.debug("TaskDetector: Found image in message") | |
| # Get text content | |
| if b_type == "text": | |
| text = get_block_attr(block, "text", "") or "" | |
| total_text += text.lower() + " " | |
| # Analyze text for keywords | |
| if total_text: | |
| has_coding = self._detect_coding(total_text) | |
| has_reasoning = self._detect_reasoning(total_text) | |
| # Calculate confidence | |
| confidence = self._calculate_confidence( | |
| has_vision, has_coding, has_reasoning, total_text | |
| ) | |
| # Default to general text if nothing detected | |
| if not has_vision and not has_coding and not has_reasoning: | |
| has_general = True | |
| result = TaskRequirements( | |
| requires_vision=has_vision, | |
| requires_coding=has_coding, | |
| requires_reasoning=has_reasoning, | |
| requires_general_text=True, | |
| confidence=confidence, | |
| ) | |
| logger.info( | |
| "TaskDetector: detected caps={} confidence={:.2f}", | |
| result.required_capabilities, | |
| confidence, | |
| ) | |
| return result | |
| def _detect_coding(self, text: str) -> bool: | |
| """Detect if request requires coding capabilities.""" | |
| # Check exact word matches first | |
| words = set(re.findall(r"\b\w+\b", text)) | |
| coding_matches = words & CODING_KEYWORDS | |
| if len(coding_matches) >= 2: | |
| return True | |
| # Also check for substring matches (e.g., "python" in "write python code") | |
| for keyword in CODING_KEYWORDS: | |
| if keyword in text: | |
| # Found one keyword as substring, check for another | |
| remaining = text.replace(keyword, "") | |
| for kw2 in CODING_KEYWORDS: | |
| if kw2 in remaining and kw2 != keyword: | |
| return True | |
| # Also check for programming patterns | |
| if any( | |
| pat in text | |
| for pat in [ | |
| "def ", | |
| "function ", | |
| "class ", | |
| "import ", | |
| "const ", | |
| "let ", | |
| "var ", | |
| "()", | |
| "=>", | |
| ] | |
| ): | |
| return True | |
| return False | |
| def _detect_reasoning(self, text: str) -> bool: | |
| """Detect if request requires reasoning capabilities.""" | |
| words = set(re.findall(r"\b\w+\b", text)) | |
| reasoning_matches = words & REASONING_KEYWORDS | |
| if len(reasoning_matches) >= 1: | |
| return True | |
| # Also check substring | |
| for keyword in REASONING_KEYWORDS: | |
| if keyword in text: | |
| return True | |
| return False | |
| def _calculate_confidence( | |
| self, | |
| has_vision: bool, | |
| has_coding: bool, | |
| has_reasoning: bool, | |
| text: str, | |
| ) -> float: | |
| """Calculate confidence in the detection.""" | |
| if has_vision: | |
| return 0.95 # Image detection is reliable | |
| if has_coding or has_reasoning: | |
| # More text = more confident | |
| word_count = len(text.split()) | |
| base = 0.7 | |
| if word_count > 50: | |
| base = 0.8 | |
| if word_count > 100: | |
| base = 0.85 | |
| return base | |
| return 0.5 # Default confidence for general text | |
| def get_priority_hint(self, requirements: TaskRequirements) -> str: | |
| """Get a hint for model priority based on requirements.""" | |
| if requirements.requires_vision: | |
| return "vision" | |
| if requirements.requires_coding: | |
| return "coding" | |
| if requirements.requires_reasoning: | |
| return "reasoning" | |
| return "balanced" | |