Deltacorvi's picture
Upload 11 files
7224b0b verified
"""
Utility functions for the Gemini AI Agent.
"""
import re
import logging
from typing import Optional
logger = logging.getLogger(__name__)
def sanitize_input(text: str) -> str:
"""
Sanitize user input by removing potentially harmful content.
Args:
text: Raw input text
Returns:
str: Sanitized text
"""
if not isinstance(text, str):
return str(text)
# Remove excessive whitespace
text = re.sub(r'\s+', ' ', text.strip())
# Remove potential injection attempts (basic protection)
text = text.replace('\\n', '\n').replace('\\t', '\t')
return text
def format_response(response: str) -> str:
"""
Format the AI response for better readability.
Args:
response: Raw response from the AI model
Returns:
str: Formatted response
"""
if not response:
return "No response generated."
# Clean up the response
response = response.strip()
# Ensure proper spacing after periods
response = re.sub(r'\.([A-Z])', r'. \1', response)
# Fix common formatting issues
response = re.sub(r'\n\s*\n\s*\n', '\n\n', response) # Multiple newlines
response = re.sub(r'([.!?])\s*([A-Z])', r'\1 \2', response) # Spacing after punctuation
return response
def truncate_text(text: str, max_length: int = 1000) -> str:
"""
Truncate text to a maximum length while preserving word boundaries.
Args:
text: Text to truncate
max_length: Maximum length allowed
Returns:
str: Truncated text
"""
if len(text) <= max_length:
return text
# Find the last space before the max_length
truncated = text[:max_length]
last_space = truncated.rfind(' ')
if last_space > max_length * 0.8: # If space is reasonably close to end
return truncated[:last_space] + "..."
else:
return truncated + "..."
def extract_code_blocks(text: str) -> list:
"""
Extract code blocks from markdown-formatted text.
Args:
text: Text containing potential code blocks
Returns:
list: List of code blocks found
"""
code_pattern = r'```(\w+)?\n(.*?)\n```'
matches = re.findall(code_pattern, text, re.DOTALL)
return [{'language': match[0] or 'text', 'code': match[1]} for match in matches]
def validate_question(question: str) -> tuple[bool, Optional[str]]:
"""
Validate if a question is appropriate and well-formed.
Args:
question: The question to validate
Returns:
tuple: (is_valid, error_message)
"""
if not question or not question.strip():
return False, "Question cannot be empty."
if len(question.strip()) < 3:
return False, "Question is too short. Please provide more detail."
if len(question) > 5000:
return False, "Question is too long. Please keep it under 5000 characters."
return True, None
def format_error_message(error: Exception) -> str:
"""
Format error messages for user display.
Args:
error: The exception that occurred
Returns:
str: User-friendly error message
"""
error_type = type(error).__name__
# Map common errors to user-friendly messages
error_messages = {
'ConnectionError': 'Unable to connect to the AI service. Please check your internet connection.',
'TimeoutError': 'The request timed out. Please try again with a shorter question.',
'ValueError': 'Invalid input provided. Please check your question format.',
'KeyError': 'Configuration error. Please check your API settings.',
'PermissionError': 'Access denied. Please check your API key permissions.'
}
user_message = error_messages.get(error_type, f"An unexpected error occurred: {str(error)}")
logger.error(f"Error formatted for user: {error_type} - {str(error)}")
return user_message