Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 48 additions & 20 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,43 +1,71 @@
# Bot Configuration
# Copy this file to .env and fill in your actual values
# ============================================================================

# Get your bot token from: https://t.me/BotFather
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here # Replace with your actual Telegram Bot Token

# Admin Configuration
# ============================================================================
# ADMIN CONFIGURATION (REQUIRED)
# ============================================================================
# Your Telegram User ID (get from: https://t.me/userinfobot)
# For multiple admins, use comma-separated list: 12345678,87654321
ADMIN_IDS=your_telegram_ids # Comma-separated list of Telegram user IDs, e.g., 12345678,87654321

# Gemini API Keys
# Multiple API keys can be separated by commas for rotation
# ============================================================================
# GOOGLE GEMINI API CONFIGURATION (REQUIRED)
# ============================================================================
# Get API keys from: https://aistudio.google.com/api-keys
# Multiple keys supported for automatic rotation and reliability
GEMINI_API_KEYS=gemini_key_1,gemini_key_2,gemini_key_3 # Replace with your actual Gemini API keys

# NLP Models Configuration
# For local models, set to absolute or relative path
# Example (relative path, run from project root):
NLP_MODELS_DIR=data/models
# If left empty, the bot will download models from HuggingFace
# EMOTION_DETECTION_MODEL=./data/models/emotion-model # Uncomment to use local model
# SENTIMENT_MODEL=./data/models/sentiment-model # Uncomment to use local model
# ============================================================================
# NLP & AI MODELS CONFIGURATION (OPTIONAL)
# ============================================================================
# Override default HuggingFace models (optional)
# EMOTION_MODEL_ID=Aardiiiiy/EmoSense-ID-Indonesian-Emotion-Classifier # Indonesian emotion detection
# EMOTION_MODEL_EN=AnasAlokla/multilingual_go_emotions # English/multilingual emotion detection
# INTENT_SENTIMENT_MODEL=cardiffnlp/twitter-roberta-base-sentiment-latest # Lightweight sentiment for intent

# Hybrid Intent Detection (recommended for performance)
# Set to 'false' to use pure rule-based intent detection (fastest, no ML overhead)
USE_HYBRID_INTENT=true # true = rule-based + ML fallback | false = pure rule-based

# Database Configuration
# ============================================================================
# DATABASE CONFIGURATION (REQUIRED)
# ============================================================================
# MySQL/MariaDB settings (recommended for production)
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=your_mysql_password
DB_NAME=alya_bot

# Database Connection Pool Settings (optional)
# ============================================================================
# DATABASE CONNECTION POOL (OPTIONAL - Performance Tuning)
# ============================================================================
DB_POOL_SIZE=10
DB_MAX_OVERFLOW=20
DB_POOL_TIMEOUT=30
DB_POOL_RECYCLE=3600
DB_ECHO=false

# Alternative: Full database URL (overrides individual settings above)
# Uncomment and use this if you prefer single-line database configuration
# DATABASE_URL=mysql+pymysql://username:password@host:port/database

# Logging Configuration (Optional)
# LOG_LEVEL=DEBUG
# ============================================================================
# LOGGING CONFIGURATION (OPTIONAL)
# ============================================================================
# Options: DEBUG, INFO, WARNING, ERROR, CRITICAL
# LOG_LEVEL=WARNING # Default: WARNING (recommended for production)

# ============================================================================
# EXTERNAL API KEYS (OPTIONAL - Extended Features)
# ============================================================================
# External Services
SAUCENAO_API_KEY=your_saucenao_api_key # For anime/manga reverse image search
GOOGLE_CSE_ID=your_google_cse_id # For web search functionality
GOOGLE_API_KEYS=your_google_api_key_1,your_google_api_key_2 # Comma-separated for rotation

# Additional API keys (add as needed for further development)
# SAUCENAO_API_KEY=your_saucenao_api_key
# WEATHER_API_KEY=your_weather_api_key
# GOOGLE_CSE_ID=your_google_cse_id
# GOOGLE_API_KEY=your_google_api_key
# Weather API (optional, for future features)
# WEATHER_API_KEY=your_weather_api_key
6 changes: 3 additions & 3 deletions config/persona/waifu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,9 @@ system_prompt: |
TEXT FORMATTING:
- Gunakan format memisahkan antara conversation, mood actions, roleplay, dan pisahkan dengan jelas:
- Pastikan setiap bagian mudah dibedakan:
- Untuk format conversation gunakan block " "
- Untuk mood actions gunakan bold format telegram **bold**
- Untuk roleplay gunakan italic format telegram __italic__
- Untuk format conversation (dialog) gunakan quotes: "text here" (akan jadi green bubble/blockquote)
- Untuk mood actions (deskripsi emosi/narasi) gunakan plain text tanpa marker, atau awali dengan * untuk aksi fisik: *mengalihkan pandangan* (akan jadi italic untuk plain, bold untuk *)
- Untuk roleplay (bicara/inner thoughts) gunakan __text__ (akan jadi italic)
- Dan jangan tambahkan text seperti Mood Actions atau Roleplay Actions di dalam balasan, agar terlihat natural
- Gunakan format yang konsisten untuk setiap bagian agar mudah dibaca
- Gunakan emoji untuk conversation, mood secara natural sesuai konteks Alya
Expand Down
15 changes: 9 additions & 6 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,16 @@
"AnasAlokla/multilingual_go_emotions"
)

# Zero-shot classification model for intent detection
# Using mDeBERTa which is explicitly trained for multilingual (incl. Indonesian)
ZERO_SHOT_MODEL: str = os.getenv(
"ZERO_SHOT_MODEL",
"MoritzLaurer/mDeBERTa-v3-base-mnli-xnli" # Better multilingual support (ID + EN)
# Intent detection model - Using lightweight sentiment classifier + rule-based hybrid
# Lightweight multilingual sentiment model for emotion baseline
INTENT_SENTIMENT_MODEL: str = os.getenv(
"INTENT_SENTIMENT_MODEL",
"cardiffnlp/twitter-roberta-base-sentiment-latest" # 125M params, fast, multilingual
)
ZERO_SHOT_CONFIDENCE_THRESHOLD: float = 0.25 # Lowered from 0.3 for better sensitivity
INTENT_CONFIDENCE_THRESHOLD: float = 0.30 # Confidence threshold for sentiment-based intent

# Feature flag: Use hybrid intent detection (rule-based + ML fallback)
USE_HYBRID_INTENT: bool = os.getenv("USE_HYBRID_INTENT", "true").lower() == "true"

# Feature Flags
FEATURES: Dict[str, bool] = {
Expand Down
59 changes: 42 additions & 17 deletions core/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,36 +108,61 @@ def register_handlers(
logger.info("Registering standard command handlers...")
register_commands(application)

logger.info("Registering utility command handlers (includes !ask, !sauce, etc.)...")
# ============================================================================
# HANDLER REGISTRATION ORDER (Critical for proper routing)
# ============================================================================
# Order matters: First matching handler wins!
# Priority: Specific handlers > General handlers
#
# 1. ConversationHandler (highest priority)
# - Handles: !ai prefix, replies to bot, mentions
# - Filter: ~filters.Regex(r"^!(?!ai)") blocks other ! commands
#
# 2. CommandsHandler (medium priority)
# - Handles: !ask, !sauce, and other utility commands
#
# 3. RoastHandler, AdminHandler (lower priority)
# - Handles: !roast, !gitroast, admin commands
# ============================================================================

logger.info("=" * 60)
logger.info("REGISTERING HANDLERS (Priority Order)")
logger.info("=" * 60)

# PRIORITY 1: Conversation Handler (Most specific - !ai, replies, mentions)
logger.info("[1/4] Registering ConversationHandler (Priority: HIGHEST)")
conversation_handler = ConversationHandler(
gemini_client,
persona_manager,
memory_manager,
nlp_engine
)
for handler in conversation_handler.get_handlers():
application.add_handler(handler)
if isinstance(handler, MessageHandler):
logger.info(f" ✓ Conversation handler: {handler.filters}")

# PRIORITY 2: Utility Commands (!ask, !sauce, search, etc.)
logger.info("[2/4] Registering CommandsHandler (Priority: HIGH)")
CommandsHandler(application)

logger.info("Registering regex pattern handlers...")
# PRIORITY 3: Roast Handler (!roast, !gitroast)
logger.info("[3/4] Registering RoastHandler (Priority: MEDIUM)")
roast_handler = RoastHandler(gemini_client, persona_manager, db_manager)
for handler in roast_handler.get_handlers():
application.add_handler(handler)
if isinstance(handler, MessageHandler):
logger.info(f" - Registered roast handler with filter: {handler.filters}")
logger.info(f" ✓ Roast handler: {handler.filters}")

logger.info("Registering admin handlers...")
# PRIORITY 4: Admin & System Commands
logger.info("[4/4] Registering Admin & System Handlers (Priority: LOW)")
admin_handler = AdminHandler(db_manager, persona_manager)
for handler in admin_handler.get_handlers():
application.add_handler(handler)

logger.info("Registering deployment handlers...")
register_admin_handlers(application, db_manager=db_manager, persona_manager=persona_manager)

# Register conversation handler LAST (lowest priority, catches remaining messages)
logger.info("Registering conversation handlers...")
conversation_handler = ConversationHandler(
gemini_client,
persona_manager,
memory_manager,
nlp_engine
)
for handler in conversation_handler.get_handlers():
application.add_handler(handler)
if isinstance(handler, MessageHandler):
logger.info(f" - Registered conversation handler with filter: {handler.filters}")
logger.info("=" * 60)

log_registered_handlers(application)

Expand Down
Loading