Team Ai
Apppublic

Yash030/claude-code-proxy

sourceHugging Faceupdated 5mo agoView on Hugging Face
2likes
task_detector.py298 linesDownload Raw Back to core
1"""Task detection - analyze requests to determine required capabilities."""2 3from __future__ import annotations4 5import re6from dataclasses import dataclass7from typing import Any8 9from loguru import logger10 11from core.anthropic.content import get_block_attr12 13 14# Keywords that indicate specific task types15CODING_KEYWORDS = {16    "python",17    "javascript",18    "typescript",19    "java",20    "c++",21    "cpp",22    "golang",23    "rust",24    "ruby",25    "php",26    "swift",27    "kotlin",28    "sql",29    "html",30    "css",31    "react",32    "vue",33    "angular",34    "node",35    "django",36    "flask",37    "fastapi",38    "spring",39    "function",40    "class",41    "method",42    "api",43    "endpoint",44    "database",45    "query",46    "algorithm",47    "debug",48    "error",49    "fix",50    "implement",51    "create",52    "write",53    "code",54    "programming",55    "script",56    "module",57    "import",58    "export",59    "def ",60    "const ",61    "let ",62    "var ",63    "function ",64    "async ",65    "await ",66}67 68REASONING_KEYWORDS = {69    "analyze",70    "analysis",71    "reason",72    "why",73    "how",74    "explain",75    "compare",76    "contrast",77    "evaluate",78    "assess",79    "conclude",80    "deduce",81    "infer",82    "logic",83    "proof",84    "theorem",85    "hypothesis",86    "synthesize",87    "strategy",88    "think",89    "solve",90    "derive",91    "calculate",92    "compute",93    "math",94    "equation",95    "formula",96    "solution",97    "optimal",98    "best",99    "improve",100    "optimize",101    "design",102    "architecture",103    "system",104    "plan",105    "decision",106    "recommend",107}108 109VISION_KEYWORDS = {110    "image",111    "picture",112    "photo",113    "screenshot",114    "diagram",115    "chart",116    "graph",117    "visual",118    "see",119    "look at",120    "describe what",121    "what's in",122    "identify",123    "recognize",124    "detect",125    "object",126    "scene",127    "face",128    "text in image",129}130 131 132@dataclass(frozen=True, slots=True)133class TaskRequirements:134    """Detected requirements for a request."""135 136    requires_vision: bool = False137    requires_coding: bool = False138    requires_reasoning: bool = False139    requires_general_text: bool = True140    confidence: float = 0.0  # 0-1 confidence in detection141 142    @property143    def required_capabilities(self) -> set[str]:144        caps = set()145        if self.requires_vision:146            caps.add("vision")147        if self.requires_coding:148            caps.add("coding")149        if self.requires_reasoning:150            caps.add("reasoning")151        if self.requires_general_text:152            caps.add("general_text")153        return caps154 155 156class TaskDetector:157    """Analyze request messages to detect required capabilities."""158 159    def detect_requirements(self, messages: list[Any]) -> TaskRequirements:160        """Analyze messages and return required capabilities."""161        has_vision = False162        has_coding = False163        has_reasoning = False164        total_text = ""165 166        for msg in messages:167            # Handle both dict and object message formats168            if isinstance(msg, dict):169                content = msg.get("content")170            elif hasattr(msg, "content"):171                content = msg.content172            else:173                continue174 175            if isinstance(content, str):176                total_text += content.lower() + " "177            elif isinstance(content, list):178                for block in content:179                    b_type = get_block_attr(block, "type") or ""180 181                    # Check for image content182                    if b_type == "image":183                        has_vision = True184                        logger.debug("TaskDetector: Found image in message")185 186                    # Get text content187                    if b_type == "text":188                        text = get_block_attr(block, "text", "") or ""189                        total_text += text.lower() + " "190 191        # Analyze text for keywords192        if total_text:193            has_coding = self._detect_coding(total_text)194            has_reasoning = self._detect_reasoning(total_text)195 196        # Calculate confidence197        confidence = self._calculate_confidence(198            has_vision, has_coding, has_reasoning, total_text199        )200 201        # Default to general text if nothing detected202        if not has_vision and not has_coding and not has_reasoning:203            has_general = True204 205        result = TaskRequirements(206            requires_vision=has_vision,207            requires_coding=has_coding,208            requires_reasoning=has_reasoning,209            requires_general_text=True,210            confidence=confidence,211        )212 213        logger.info(214            "TaskDetector: detected caps={} confidence={:.2f}",215            result.required_capabilities,216            confidence,217        )218 219        return result220 221    def _detect_coding(self, text: str) -> bool:222        """Detect if request requires coding capabilities."""223        # Check exact word matches first224        words = set(re.findall(r"\b\w+\b", text))225        coding_matches = words & CODING_KEYWORDS226        if len(coding_matches) >= 2:227            return True228 229        # Also check for substring matches (e.g., "python" in "write python code")230        for keyword in CODING_KEYWORDS:231            if keyword in text:232                # Found one keyword as substring, check for another233                remaining = text.replace(keyword, "")234                for kw2 in CODING_KEYWORDS:235                    if kw2 in remaining and kw2 != keyword:236                        return True237                # Also check for programming patterns238                if any(239                    pat in text240                    for pat in [241                        "def ",242                        "function ",243                        "class ",244                        "import ",245                        "const ",246                        "let ",247                        "var ",248                        "()",249                        "=>",250                    ]251                ):252                    return True253 254        return False255 256    def _detect_reasoning(self, text: str) -> bool:257        """Detect if request requires reasoning capabilities."""258        words = set(re.findall(r"\b\w+\b", text))259        reasoning_matches = words & REASONING_KEYWORDS260        if len(reasoning_matches) >= 1:261            return True262        # Also check substring263        for keyword in REASONING_KEYWORDS:264            if keyword in text:265                return True266        return False267 268    def _calculate_confidence(269        self,270        has_vision: bool,271        has_coding: bool,272        has_reasoning: bool,273        text: str,274    ) -> float:275        """Calculate confidence in the detection."""276        if has_vision:277            return 0.95  # Image detection is reliable278        if has_coding or has_reasoning:279            # More text = more confident280            word_count = len(text.split())281            base = 0.7282            if word_count > 50:283                base = 0.8284            if word_count > 100:285                base = 0.85286            return base287        return 0.5  # Default confidence for general text288 289    def get_priority_hint(self, requirements: TaskRequirements) -> str:290        """Get a hint for model priority based on requirements."""291        if requirements.requires_vision:292            return "vision"293        if requirements.requires_coding:294            return "coding"295        if requirements.requires_reasoning:296            return "reasoning"297        return "balanced"298