Download gemini_service.py from imkrish/chatbot: direct link, hf CLI and curl.
- Browser
- Download file 7.92 kB
-
https://huggingface.co/spaces/imkrish/chatbot/resolve/main/gemini_service.py
- Command line
-
hf download hf://spaces/imkrish/chatbot/gemini_service.py
-
curl -L -o gemini_service.py https://huggingface.co/spaces/imkrish/chatbot/resolve/main/gemini_service.py
7.92 kB
| """ | |
| Gemini AI Service for Enhanced NLP Understanding | |
| Uses Google's Gemini API for better intent detection and conversational responses | |
| """ | |
| import os | |
| import logging | |
| import json | |
| import re | |
| from typing import Dict, List, Optional, Tuple | |
| logger = logging.getLogger("chatbot.gemini") | |
| # Try to import google.generativeai | |
| try: | |
| import google.generativeai as genai | |
| GEMINI_AVAILABLE = True | |
| except ImportError: | |
| GEMINI_AVAILABLE = False | |
| logger.warning("google-generativeai not installed. Gemini features disabled.") | |
| class GeminiService: | |
| def __init__(self, api_key: Optional[str] = None): | |
| self.api_key = api_key or os.getenv('GEMINI_API_KEY') | |
| self.model = None | |
| self.initialized = False | |
| if GEMINI_AVAILABLE and self.api_key: | |
| try: | |
| genai.configure(api_key=self.api_key) | |
| self.model = genai.GenerativeModel('gemini-1.5-flash') | |
| self.initialized = True | |
| logger.info("Gemini AI service initialized successfully") | |
| except Exception as e: | |
| logger.error(f"Failed to initialize Gemini: {e}") | |
| else: | |
| if not GEMINI_AVAILABLE: | |
| logger.warning("Gemini library not available") | |
| if not self.api_key: | |
| logger.warning("GEMINI_API_KEY not set") | |
| def is_available(self) -> bool: | |
| """Check if Gemini service is available""" | |
| return self.initialized and self.model is not None | |
| def classify_intent(self, user_message: str) -> Tuple[str, float, Dict]: | |
| """ | |
| Use Gemini to classify user intent with high accuracy | |
| Returns: (intent, confidence, extracted_entities) | |
| """ | |
| if not self.is_available(): | |
| return 'unknown', 0.0, {} | |
| prompt = f"""You are an intent classifier for CampVerse, a college event discovery platform. | |
| Analyze the following user message and classify it into ONE of these intents: | |
| - greeting: User says hi, hello, hey, good morning, etc. | |
| - farewell: User says bye, goodbye, see you, etc. | |
| - thanks: User expresses gratitude | |
| - event_search: User is looking for events, hackathons, workshops, competitions, etc. | |
| - event_details: User wants details about a specific event | |
| - registration_help: User wants help with event registration | |
| - host_help: User wants to host/organize an event | |
| - account_help: User has account/profile related questions | |
| - general_question: General questions about the platform | |
| - feedback: User giving feedback or suggestions | |
| Also extract any relevant entities like: | |
| - event_type: hackathon, workshop, seminar, webinar, competition, etc. | |
| - time_frame: today, tomorrow, this week, upcoming, etc. | |
| - topic: AI, ML, web development, coding, etc. | |
| - location: any mentioned location | |
| User message: "{user_message}" | |
| Respond in this exact JSON format: | |
| {{ | |
| "intent": "intent_name", | |
| "confidence": 0.95, | |
| "entities": {{ | |
| "event_type": null, | |
| "time_frame": null, | |
| "topic": null, | |
| "location": null | |
| }}, | |
| "reasoning": "brief explanation" | |
| }}""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| response_text = response.text.strip() | |
| # Extract JSON from response | |
| json_match = re.search(r'\{[\s\S]*\}', response_text) | |
| if json_match: | |
| result = json.loads(json_match.group()) | |
| intent = result.get('intent', 'general_question') | |
| confidence = result.get('confidence', 0.8) | |
| entities = result.get('entities', {}) | |
| logger.info(f"Gemini classified intent: {intent} ({confidence}) for: {user_message}") | |
| return intent, confidence, entities | |
| else: | |
| logger.warning(f"Could not parse Gemini response: {response_text}") | |
| return 'general_question', 0.5, {} | |
| except Exception as e: | |
| logger.error(f"Gemini intent classification failed: {e}") | |
| return 'unknown', 0.0, {} | |
| def generate_response(self, user_message: str, intent: str, entities: Dict, | |
| events: Optional[List[Dict]] = None, context: str = "") -> str: | |
| """ | |
| Generate a natural, conversational response using Gemini | |
| """ | |
| if not self.is_available(): | |
| return None | |
| # Build context about available events | |
| events_context = "" | |
| if events: | |
| events_context = "\n\nAvailable events:\n" | |
| for i, event in enumerate(events[:5], 1): | |
| title = event.get('title', 'Untitled') | |
| date = event.get('date', 'TBA')[:10] if event.get('date') else 'TBA' | |
| desc = event.get('description', '')[:100] | |
| event_type = event.get('type', 'event') | |
| tags = ', '.join(event.get('tags', [])[:3]) | |
| events_context += f"{i}. {title} ({event_type})\n Date: {date}\n Tags: {tags}\n Description: {desc}...\n\n" | |
| prompt = f"""You are CampVerseBot, a friendly and helpful assistant for CampVerse - a college event discovery platform. | |
| User's message: "{user_message}" | |
| Detected intent: {intent} | |
| Extracted entities: {json.dumps(entities)} | |
| {events_context} | |
| {context} | |
| Guidelines: | |
| - Be friendly, concise, and helpful | |
| - If events are provided, recommend them naturally | |
| - For event searches, list events with dates and brief descriptions | |
| - Use emojis sparingly for a friendly tone | |
| - If no events match, suggest alternative searches | |
| - For greetings, introduce yourself briefly | |
| - For help requests, explain what you can do | |
| - Keep responses under 200 words unless listing multiple events | |
| Generate a natural, helpful response:""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| generated_text = response.text.strip() | |
| logger.info(f"Gemini generated response for intent: {intent}") | |
| return generated_text | |
| except Exception as e: | |
| logger.error(f"Gemini response generation failed: {e}") | |
| return None | |
| def enhance_search_query(self, user_message: str, entities: Dict) -> str: | |
| """ | |
| Use Gemini to extract better search keywords from user message | |
| """ | |
| if not self.is_available(): | |
| return user_message | |
| prompt = f"""Extract the main search keywords from this event search query. | |
| User message: "{user_message}" | |
| Entities detected: {json.dumps(entities)} | |
| Return only the key search terms separated by spaces (no explanation, just the keywords):""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| keywords = response.text.strip() | |
| logger.info(f"Enhanced search query: {keywords}") | |
| return keywords if keywords else user_message | |
| except Exception as e: | |
| logger.error(f"Query enhancement failed: {e}") | |
| return user_message | |
| def get_contextual_response(self, intent: str) -> Optional[str]: | |
| """ | |
| Get quick responses for simple intents without API call | |
| """ | |
| quick_responses = { | |
| 'greeting': "Hi there! ๐ I'm CampVerseBot, your campus event assistant. I can help you discover hackathons, workshops, seminars, and more! What are you looking for today?", | |
| 'farewell': "Goodbye! ๐ Feel free to come back anytime you need help finding events. Have a great day!", | |
| 'thanks': "You're welcome! ๐ Let me know if there's anything else I can help you with!", | |
| } | |
| return quick_responses.get(intent) | |
| # Singleton instance | |
| _gemini_service = None | |
| def get_gemini_service() -> GeminiService: | |
| """Get or create the singleton Gemini service instance""" | |
| global _gemini_service | |
| if _gemini_service is None: | |
| _gemini_service = GeminiService() | |
| return _gemini_service | |