Spaces:
Sleeping
Sleeping
File size: 4,916 Bytes
b482b16 268baab | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | """
Input handler for processing and validating user messages.
Handles numeric inputs, validation, and interpretation.
"""
import re
from src.rag.utilclasses import ConversationState
from src.utils.logging import get_logger
logger = get_logger("input_handler")
class InputHandler:
"""Handles input validation and interpretation"""
@staticmethod
def validate_and_normalize(message: str) -> str:
"""
Normalize and validate user input.
Args:
message: Raw user input
Returns:
Normalized message
"""
if not message:
return ""
# Strip whitespace
normalized = message.strip()
# Handle empty or very short inputs
if len(normalized) < 1:
return ""
return normalized
@staticmethod
def is_numeric_input(message: str) -> bool:
"""
Check if message is a standalone number.
Args:
message: User input
Returns:
True if message is just a number
"""
normalized = message.strip()
# Check if it's just digits (possibly with decimal)
return bool(re.match(r'^\d+(\.\d+)?$', normalized))
@staticmethod
def interpret_numeric_input(
message: str,
conversation_history: list
) -> str:
"""
Interpret standalone numeric input based on conversation context.
Args:
message: Numeric input (e.g., "5")
conversation_history: Recent conversation messages (LangChain message objects)
Returns:
Interpreted message (e.g., "I have 5 years of experience")
"""
number = message.strip()
# Look at recent messages for context
recent_context = ""
if len(conversation_history) > 0:
# Get last bot message
# Import here to avoid circular dependency
from langchain_core.messages import AIMessage
for msg in reversed(conversation_history):
# Handle LangChain message objects
if isinstance(msg, AIMessage):
recent_context = msg.content.lower() if hasattr(msg, 'content') else ""
break
# Handle dictionary format (for backward compatibility)
elif isinstance(msg, dict) and msg.get("role") == "assistant":
recent_context = msg.get("content", "").lower()
break
# Interpret based on context keywords
if any(keyword in recent_context for keyword in [
"experience", "years", "worked", "arbeits", "erfahrung", "jahre"
]):
logger.info(f"Interpreting numeric input '{number}' as years of experience")
return f"I have {number} years of work experience"
elif any(keyword in recent_context for keyword in [
"age", "old", "alter", "jahre alt"
]):
logger.info(f"Interpreting numeric input '{number}' as age")
return f"I am {number} years old"
elif any(keyword in recent_context for keyword in [
"qualification", "degree", "bachelor", "master", "qualifikation"
]):
logger.info(f"Interpreting numeric input '{number}' as qualification level")
# Interpret as degree type
level_map = {
"1": "I have a Bachelor's degree",
"2": "I have a Master's degree",
"3": "I have an MBA",
"4": "I have a doctorate/PhD"
}
return level_map.get(number, f"My qualification level is {number}")
# Default: assume years of experience (most common)
logger.info(f"Interpreting numeric input '{number}' as years of experience (default)")
return f"I have {number} years of work experience"
@staticmethod
def process_input(
message: str,
conversation_history: list
) -> tuple[str, bool]:
"""
Process user input with validation and interpretation.
Args:
message: Raw user input
conversation_history: Recent messages for context
Returns:
Tuple of (processed_message, is_valid)
"""
# Normalize
normalized = InputHandler.validate_and_normalize(message)
if not normalized:
return "", False
# Check if numeric
if InputHandler.is_numeric_input(normalized):
interpreted = InputHandler.interpret_numeric_input(
normalized,
conversation_history
)
return interpreted, True
return normalized, True
|