| """ |
| Intent Router β classifies user input into one of five categories: |
| - system : /commands |
| - advanced_math : calculus, algebra, limits, matrices, series, etc. |
| - math : plain arithmetic (numbers only) |
| - knowledge : factual questions answered from the knowledge base |
| - conversation : everything else (chat, small talk, open questions) |
| """ |
|
|
| import re |
|
|
|
|
| |
| |
| |
| ADVANCED_MATH_KEYWORDS = [ |
| |
| "integrate", "integral", "antiderivative", "indefinite integral", |
| "definite integral", "β«", |
| "differentiate", "derivative", "d/dx", "d/dy", "d/dz", "d/dt", |
| "second derivative", "third derivative", "nth derivative", "partial derivative", |
| "limit of", "limit as", "lim ", "find the limit", |
| |
| "differential equation", "ode ", "dsolve", "solve the ode", |
| "y'' ", "y' ", "d2y", "d^2y", |
| |
| "solve ", "find roots", "zeros of", "find the value of x", |
| |
| "eigenvalue", "eigenvector", "determinant of", "det of", |
| "inverse matrix", "matrix inverse", "rank of matrix", "matrix rank", |
| "trace of matrix", "matrix trace", "characteristic polynomial", |
| |
| "taylor series", "maclaurin series", "series expansion", "power series", |
| "laplace transform", "laplace of", "inverse laplace", |
| "fourier transform", "fourier of", |
| |
| "simplify ", "simplify(", "factor ", "factorise", "factorize", |
| "expand ", "partial fraction", |
| |
| "gcd(", "gcd of", "greatest common divisor", "highest common factor", |
| "lcm(", "lcm of", "least common multiple", |
| "prime factor", "prime factorization", |
| " mod ", "modulo ", "modular inverse", |
| |
| "mean of", "average of", "median of", "variance of", |
| "standard deviation of", "std dev of", |
| |
| "factorial of", "factorial(", "binomial coefficient", |
| "choose ", "nCr", "nPr", "permutation", |
| |
| "sum of ", "summation of", "β", "β", |
| |
| "complex number", "real part of", "imaginary part of", |
| "modulus of", "argument of", "conjugate of", |
| |
| "simplify trig", "trig simplif", "trigonometric simplif", |
| ] |
|
|
| |
| MATH_PATTERN = re.compile( |
| r""" |
| ^ # start of string |
| \s* # optional leading whitespace |
| [\d\s\(\)] # starts with digit, space, or parenthesis |
| [\d\s\+\-\*\/\%\^\(\)\.]* # followed by math characters |
| $ # end of string |
| """, |
| re.VERBOSE, |
| ) |
|
|
| ARITHMETIC_PREFIXES = ("calculate", "compute", "evaluate", "what is") |
|
|
| |
| KNOWLEDGE_KEYWORDS = [ |
| "what is", "what are", "who is", "who are", "explain", "define", |
| "tell me about", "describe", "how does", "why is", "when was", |
| "where is", "history of", "meaning of", "difference between", |
| "knowledge", "information about", "learn about", "facts about", |
| ] |
|
|
| |
| SYSTEM_PATTERN = re.compile(r"^/\w+") |
|
|
|
|
| def classify_intent(user_input: str) -> str: |
| """ |
| Classify user input and return one of: |
| 'system' | 'advanced_math' | 'math' | 'knowledge' | 'conversation' |
| """ |
| text = user_input.strip() |
| lowered = text.lower() |
|
|
| |
| if SYSTEM_PATTERN.match(text): |
| return "system" |
|
|
| |
| for kw in ADVANCED_MATH_KEYWORDS: |
| if kw in lowered: |
| return "advanced_math" |
|
|
| |
| if _is_simple_arithmetic(text, lowered): |
| return "math" |
|
|
| |
| for kw in KNOWLEDGE_KEYWORDS: |
| if kw in lowered: |
| return "knowledge" |
|
|
| |
| return "conversation" |
|
|
|
|
| def _is_simple_arithmetic(text: str, lowered: str) -> bool: |
| """True if the input is a plain numeric arithmetic expression.""" |
| |
| remainder = lowered |
| for prefix in ARITHMETIC_PREFIXES: |
| if lowered.startswith(prefix): |
| remainder = lowered[len(prefix):].strip() |
| break |
|
|
| |
| has_digit = any(ch.isdigit() for ch in remainder) |
| has_operator = any(ch in "+-*/%^" for ch in remainder) |
| |
| has_letters = bool(re.search(r'[a-zA-Z]', remainder)) |
|
|
| if has_digit and has_operator and not has_letters: |
| return True |
|
|
| |
| return bool(MATH_PATTERN.match(text)) |
|
|