imkrish commited on
Commit
d4e8d9b
·
0 Parent(s):

Deploy chatbot to Hugging Face Space

Browse files
Files changed (9) hide show
  1. .dockerignore +26 -0
  2. Dockerfile +17 -0
  3. README.md +306 -0
  4. app.py +176 -0
  5. cli_chat.py +54 -0
  6. event_service.py +117 -0
  7. faq.json +373 -0
  8. intent_classifier.py +105 -0
  9. requirements.txt +11 -0
.dockerignore ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ .Python
6
+ *.so
7
+ *.egg
8
+ *.egg-info
9
+ dist
10
+ build
11
+ .git
12
+ .gitignore
13
+ .env
14
+ .env.local
15
+ *.log
16
+ .DS_Store
17
+ .vscode
18
+ .idea
19
+ *.md
20
+ venv
21
+ env
22
+ .pytest_cache
23
+ .coverage
24
+ htmlcov
25
+ cli_chat.py
26
+ tests
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Hugging Face Spaces Dockerfile template
3
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
4
+ FROM python:3.9
5
+
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV PATH="/home/user/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=user ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+
15
+ COPY --chown=user . /app
16
+
17
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CampVerse Chatbot Microservice
2
+
3
+ ## Quick Start for New Users
4
+
5
+
6
+ If you're new and want to run this chatbot microservice, you can choose either Docker or Python. Both methods are described below:
7
+
8
+ ---
9
+
10
+ ### 🚀 Run via Python (Local Development)
11
+
12
+ 1. **Clone the Repository**
13
+ ```bash
14
+ git clone https://github.com/CcpC-cuj/CampVerse.git
15
+ cd CampVerse/ML/chatbot
16
+ ```
17
+
18
+ 2. **Install Python & Dependencies**
19
+ Make sure you have Python 3.10+ installed. Then install dependencies:
20
+ ```bash
21
+ pip install -r requirements.txt
22
+ ```
23
+
24
+ 3. **Start the Backend Service**
25
+ ```bash
26
+ export BACKEND_URL=http://localhost:5001 # Set backend URL
27
+ uvicorn app:app_socket --host 0.0.0.0 --port 8000
28
+ ```4. **Test with CLI Chat Client**
29
+ Open a new terminal and run:
30
+ ```bash
31
+ python cli_chat.py
32
+ ```
33
+ Type your questions and interact with the bot.
34
+
35
+ ---
36
+
37
+ ### 🐳 Run via Docker (Containerized)
38
+
39
+ 1. **Build the Docker Image**
40
+ ```bash
41
+ docker build -t chatbot-service .
42
+ ```
43
+
44
+ 2. **Run the Docker Container**
45
+ ```bash
46
+ docker run -p 8000:8000 -e BACKEND_URL=http://localhost:5001 chatbot-service
47
+ ```3. **Test the Service**
48
+ - REST API:
49
+ ```bash
50
+ curl -X POST http://localhost:8000/chatbot -H "Content-Type: application/json" -d '{"question":"How do I register?"}'
51
+ ```
52
+ - Socket.IO:
53
+ ```bash
54
+ python cli_chat.py
55
+ ```
56
+
57
+ ---
58
+
59
+ ### 🌐 Integrate with Your Web App
60
+ Use REST API or Socket.IO as shown below to connect your frontend.
61
+
62
+ ---
63
+
64
+ A production-ready chatbot microservice using FastAPI, Socket.IO, and sentence transformers for FAQ-based question answering.
65
+
66
+ ## Features
67
+
68
+ - 🚀 **FastAPI REST API**: HTTP endpoint for Q&A
69
+ - 🔌 **Socket.IO Real-time**: WebSocket support for live chat
70
+ - 🤖 **AI-Powered**: Uses sentence transformers and FAISS for semantic search
71
+ - 🎯 **Intent Classification**: Detects greetings, event queries, help requests, and more
72
+ - 🔍 **Dynamic Event Discovery**: Fetches and searches live events from backend API
73
+ - 🐳 **Docker Ready**: Containerized for easy deployment
74
+ - 📝 **Logging**: Comprehensive logging for debugging
75
+ - ✅ **Input Validation**: Validates question length and content
76
+ - 🌐 **CORS Enabled**: Ready for frontend integration
77
+
78
+ ## Architecture
79
+
80
+ ```
81
+ ┌─────────────────┐
82
+ │ Frontend │
83
+ │ (React/Web) │
84
+ └────────┬────────┘
85
+ │
86
+ │ HTTP POST /chatbot
87
+ │ OR Socket.IO
88
+ │
89
+ ┌────────▼────────┐
90
+ │ app.py │
91
+ │ FastAPI + │
92
+ │ Socket.IO │
93
+ └────────┬────────┘
94
+ │
95
+ │ Semantic Search
96
+ │
97
+ ┌────────▼────────┐
98
+ │ faq.json │
99
+ │ (FAQ Database) │
100
+ └─────────────────┘
101
+ ```
102
+
103
+ ## API Endpoints
104
+
105
+ ### REST API
106
+
107
+ **POST /chatbot**
108
+ ```json
109
+ Request:
110
+ {
111
+ "question": "How do I register?"
112
+ }
113
+
114
+ Response:
115
+ {
116
+ "question": "How do I register?",
117
+ "answer": "Click on the Register button..."
118
+ }
119
+ ```
120
+
121
+ ### Socket.IO Events
122
+
123
+ **Client → Server**
124
+ - `user_question`: Send a question
125
+ ```javascript
126
+ socket.emit('user_question', { question: 'How do I login?' });
127
+ ```
128
+
129
+ **Server → Client**
130
+ - `bot_answer`: Receive answer
131
+ ```javascript
132
+ socket.on('bot_answer', (data) => {
133
+ console.log(data.answer);
134
+ });
135
+ ```
136
+
137
+ ## Setup & Installation
138
+
139
+ ### Local Development
140
+
141
+ 1. **Install dependencies:**
142
+ ```bash
143
+ pip install -r requirements.txt
144
+ ```
145
+
146
+ 2. **Run the server:**
147
+ ```bash
148
+ uvicorn app:app_socket --host 0.0.0.0 --port 8000
149
+ ```
150
+
151
+ 3. **Test with CLI client:**
152
+ ```bash
153
+ python cli_chat.py
154
+ ```
155
+
156
+ ### Docker Deployment
157
+
158
+ 1. **Build the image:**
159
+ ```bash
160
+ docker build -t chatbot-service .
161
+ ```
162
+
163
+ 2. **Run the container:**
164
+ ```bash
165
+ docker run -p 8000:8000 chatbot-service
166
+ ```
167
+
168
+ 3. **Test the service:**
169
+ - REST API: `curl -X POST http://localhost:8000/chatbot -H "Content-Type: application/json" -d '{"question":"How do I register?"}'`
170
+ - Socket.IO: `python cli_chat.py`
171
+
172
+ ## Project Structure
173
+
174
+ ```
175
+ chatbot/
176
+ ├── app.py # Main backend (FastAPI + Socket.IO)
177
+ ├── cli_chat.py # CLI client for testing
178
+ ├── Dockerfile # Docker configuration
179
+ ├── faq.json # FAQ database
180
+ ├── requirements.txt # Python dependencies
181
+ └── README.md # This file
182
+ ```
183
+
184
+ ## Integration with Frontend
185
+
186
+ ### React Example (Socket.IO)
187
+
188
+ ```javascript
189
+ import io from 'socket.io-client';
190
+
191
+ const socket = io('http://localhost:8000');
192
+
193
+ socket.on('connect', () => {
194
+ console.log('Connected to chatbot');
195
+ });
196
+
197
+ socket.on('bot_answer', (data) => {
198
+ console.log('Answer:', data.answer);
199
+ });
200
+
201
+ // Send question
202
+ socket.emit('user_question', { question: 'How do I login?' });
203
+ ```
204
+
205
+ ### React Example (REST API)
206
+
207
+ ```javascript
208
+ const response = await fetch('http://localhost:8000/chatbot', {
209
+ method: 'POST',
210
+ headers: { 'Content-Type': 'application/json' },
211
+ body: JSON.stringify({ question: 'How do I login?' })
212
+ });
213
+
214
+ const data = await response.json();
215
+ console.log(data.answer);
216
+ ```
217
+
218
+ ## Configuration
219
+
220
+ ### Environment Variables
221
+
222
+ You can configure the service using environment variables:
223
+
224
+ - `PORT`: Server port (default: 8000)
225
+ - `LOG_LEVEL`: Logging level (default: INFO)
226
+
227
+ ### FAQ Management
228
+
229
+ Edit `faq.json` to add/update questions and answers:
230
+
231
+ ```json
232
+ [
233
+ {
234
+ "question": "How do I register?",
235
+ "answer": "Click on the Register button on the homepage..."
236
+ }
237
+ ]
238
+ ```
239
+
240
+ After updating, rebuild the Docker image or restart the server.
241
+
242
+ ## Monitoring & Logs
243
+
244
+ The service logs all:
245
+ - Client connections/disconnections
246
+ - Incoming questions
247
+ - Matched FAQ pairs
248
+ - Errors and warnings
249
+
250
+ View logs in Docker:
251
+ ```bash
252
+ docker logs -f <container-id>
253
+ ```
254
+
255
+ ## Security
256
+
257
+ - CORS is enabled for all origins (configure for production)
258
+ - Input validation (max 512 characters)
259
+ - Error handling to prevent crashes
260
+ - No rate limiting (add if needed for production)
261
+
262
+ ## Testing
263
+
264
+ ### Manual Testing
265
+
266
+ 1. Start the service
267
+ 2. Run CLI client: `python cli_chat.py`
268
+ 3. Type questions and verify responses
269
+
270
+ ### Testing REST API
271
+
272
+ ```bash
273
+ curl -X POST http://localhost:8000/chatbot \
274
+ -H "Content-Type: application/json" \
275
+ -d '{"question":"How do I register?"}'
276
+ ```
277
+
278
+ ## Troubleshooting
279
+
280
+ **Service won't start:**
281
+ - Check if port 8000 is available
282
+ - Verify all dependencies are installed
283
+ - Check logs for errors
284
+
285
+ **CLI client can't connect:**
286
+ - Ensure service is running on port 8000
287
+ - Check firewall settings
288
+ - Verify `python-socketio` is installed
289
+
290
+ **No answer returned:**
291
+ - Check if `faq.json` exists and is valid
292
+ - Verify the question exists in FAQ database
293
+ - Check server logs for errors
294
+
295
+ ## Future Enhancements
296
+
297
+ - [ ] Add rate limiting for production
298
+ - [ ] Add authentication for Socket.IO
299
+ - [ ] Support multiple languages
300
+ - [ ] Add conversation history
301
+ - [ ] Implement fallback responses
302
+ - [ ] Add metrics and analytics
303
+
304
+ ## License
305
+
306
+ Part of the CampVerse project.
app.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from sentence_transformers import SentenceTransformer
3
+ import faiss
4
+ import numpy as np
5
+ from fastapi import FastAPI, Request
6
+ from fastapi.middleware.cors import CORSMiddleware
7
+ from pydantic import BaseModel
8
+ import socketio
9
+ import logging
10
+ import os
11
+
12
+ # Import custom services
13
+ from event_service import EventService
14
+ from intent_classifier import IntentClassifier
15
+
16
+ # --- Logging setup ---
17
+ logging.basicConfig(level=logging.INFO)
18
+ logger = logging.getLogger("chatbot")
19
+
20
+ # --- Load resources ---
21
+ try:
22
+ df = pd.read_json('faq.json')
23
+ model = SentenceTransformer('all-MiniLM-L6-v2')
24
+ question_embeddings = model.encode(df['question'].tolist(), convert_to_tensor=True)
25
+ index = faiss.IndexFlatL2(question_embeddings.shape[1])
26
+ index.add(question_embeddings.cpu().numpy())
27
+
28
+ # Initialize event service and intent classifier
29
+ backend_url = os.getenv('BACKEND_URL', 'http://localhost:5000')
30
+ event_service = EventService(backend_url, model)
31
+ intent_classifier = IntentClassifier()
32
+
33
+ # Fetch events on startup
34
+ event_service.fetch_events()
35
+
36
+ logger.info("Resources loaded successfully.")
37
+ except Exception as e:
38
+ logger.error(f"Error loading resources: {e}")
39
+ raise
40
+
41
+ # --- FastAPI REST API ---
42
+ app = FastAPI()
43
+ app.add_middleware(
44
+ CORSMiddleware,
45
+ allow_origins=["*"],
46
+ allow_credentials=True,
47
+ allow_methods=["*"],
48
+ allow_headers=["*"],
49
+ )
50
+
51
+ class QuestionRequest(BaseModel):
52
+ question: str
53
+
54
+ @app.post("/chatbot")
55
+ async def chatbot(req: QuestionRequest, request: Request):
56
+ question = req.question.strip()
57
+ if not question:
58
+ logger.warning("Received empty question.")
59
+ return {"error": "Question cannot be empty."}
60
+ if len(question) > 512:
61
+ logger.warning("Question too long.")
62
+ return {"error": "Question too long."}
63
+ try:
64
+ # Classify intent
65
+ intent, confidence = intent_classifier.classify(question)
66
+ logger.info(f"Intent: {intent} (confidence: {confidence})")
67
+
68
+ # Handle specific intents
69
+ if intent in ['greeting', 'farewell', 'thanks', 'help', 'host_help']:
70
+ response = intent_classifier.get_response_for_intent(intent)
71
+ logger.info(f"Response for {intent}: {repr(response)}") # Debug log
72
+ return {
73
+ "question": question,
74
+ "answer": response,
75
+ "intent": intent
76
+ }
77
+
78
+ # Handle event search
79
+ if intent == 'event_search':
80
+ events = event_service.search_events(question, top_k=5)
81
+ response = event_service.format_event_response(events)
82
+ return {
83
+ "question": question,
84
+ "answer": response,
85
+ "intent": intent,
86
+ "events": events
87
+ }
88
+
89
+ # Default: FAQ search
90
+ user_question_embedding = model.encode(question, convert_to_tensor=True)
91
+ user_question_embedding_np = user_question_embedding.cpu().numpy().reshape(1, -1)
92
+ distances, indices = index.search(user_question_embedding_np, k=1)
93
+ best_match_index = indices[0][0]
94
+ retrieved_answer = df.iloc[best_match_index]['answer']
95
+ retrieved_question = df.iloc[best_match_index]['question']
96
+ logger.info(f"Answered question: {question} -> {retrieved_question}")
97
+ return {
98
+ "question": retrieved_question,
99
+ "answer": retrieved_answer,
100
+ "intent": intent
101
+ }
102
+ except Exception as e:
103
+ logger.error(f"Error processing question: {e}")
104
+ return {"error": "Internal server error."}
105
+
106
+ # --- Socket.IO real-time API ---
107
+ sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*')
108
+ app_socket = socketio.ASGIApp(sio, app)
109
+
110
+ @sio.event
111
+ def connect(sid, environ):
112
+ logger.info(f"Client connected: {sid}")
113
+
114
+ @sio.event
115
+ def disconnect(sid):
116
+ logger.info(f"Client disconnected: {sid}")
117
+
118
+ @sio.event
119
+ async def user_question(sid, data):
120
+ question = data.get('question', '').strip()
121
+ if not question:
122
+ await sio.emit('bot_answer', {'error': 'Question cannot be empty.'}, to=sid)
123
+ logger.warning(f"Empty question from {sid}")
124
+ return
125
+ if len(question) > 512:
126
+ await sio.emit('bot_answer', {'error': 'Question too long.'}, to=sid)
127
+ logger.warning(f"Long question from {sid}")
128
+ return
129
+ try:
130
+ # Classify intent
131
+ intent, confidence = intent_classifier.classify(question)
132
+ logger.info(f"Intent: {intent} (confidence: {confidence})")
133
+
134
+ # Handle specific intents
135
+ if intent in ['greeting', 'farewell', 'thanks', 'help', 'host_help']:
136
+ response = intent_classifier.get_response_for_intent(intent)
137
+ await sio.emit('bot_answer', {
138
+ 'question': question,
139
+ 'answer': response,
140
+ 'intent': intent
141
+ }, to=sid)
142
+ return
143
+
144
+ # Handle event search
145
+ if intent == 'event_search':
146
+ events = event_service.search_events(question, top_k=5)
147
+ response = event_service.format_event_response(events)
148
+ await sio.emit('bot_answer', {
149
+ 'question': question,
150
+ 'answer': response,
151
+ 'intent': intent
152
+ }, to=sid)
153
+ logger.info(f"SocketIO event search: {question}")
154
+ return
155
+
156
+ # Default: FAQ search
157
+ user_question_embedding = model.encode(question, convert_to_tensor=True)
158
+ user_question_embedding_np = user_question_embedding.cpu().numpy().reshape(1, -1)
159
+ distances, indices = index.search(user_question_embedding_np, k=1)
160
+ best_match_index = indices[0][0]
161
+ retrieved_answer = df.iloc[best_match_index]['answer']
162
+ retrieved_question = df.iloc[best_match_index]['question']
163
+ await sio.emit('bot_answer', {
164
+ 'question': retrieved_question,
165
+ 'answer': retrieved_answer,
166
+ 'intent': intent
167
+ }, to=sid)
168
+ logger.info(f"SocketIO answered: {question} -> {retrieved_question}")
169
+ except Exception as e:
170
+ await sio.emit('bot_answer', {'error': 'Internal server error.'}, to=sid)
171
+ logger.error(f"SocketIO error for {sid}: {e}")
172
+
173
+ # --- For Uvicorn ---
174
+ if __name__ == "__main__":
175
+ import uvicorn
176
+ uvicorn.run(app_socket, host="0.0.0.0", port=8000)
cli_chat.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import socketio
2
+ import sys
3
+ import threading
4
+ import time
5
+
6
+ sio = socketio.Client()
7
+ user_can_input = threading.Event()
8
+ user_can_input.set()
9
+
10
+ @sio.event
11
+ def connect():
12
+ print("\n✅ Connected to CampVerse Chatbot!")
13
+ print("Type your questions below. Press Ctrl+C to exit.\n")
14
+
15
+ @sio.event
16
+ def disconnect():
17
+ print("\n❌ Disconnected from chatbot backend.")
18
+
19
+ @sio.event
20
+ def bot_answer(data):
21
+ print("\n------------------------------")
22
+ if 'error' in data:
23
+ print(f"❌ Error: {data['error']}")
24
+ else:
25
+ print(f"🤖 Bot says: {data['answer']}")
26
+ print(f" (Matched FAQ: {data['question']})")
27
+ print("------------------------------\n")
28
+ time.sleep(2)
29
+ user_can_input.set()
30
+
31
+ def ask_user():
32
+ while True:
33
+ user_can_input.wait()
34
+ question = input("You: ")
35
+ if question.strip():
36
+ sio.emit('user_question', {'question': question})
37
+ else:
38
+ print("⚠️ Please enter a valid question.\n")
39
+ user_can_input.clear()
40
+
41
+ try:
42
+ sio.connect('http://localhost:8000')
43
+ user_thread = threading.Thread(target=ask_user)
44
+ user_thread.daemon = True
45
+ user_thread.start()
46
+ while True:
47
+ pass
48
+ except KeyboardInterrupt:
49
+ print("\n👋 Goodbye!")
50
+ sio.disconnect()
51
+ sys.exit(0)
52
+ except Exception as e:
53
+ print(f"❌ Error: {e}")
54
+ sys.exit(1)
event_service.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Event Discovery Service
3
+ Fetches and searches events from the backend API
4
+ """
5
+ import requests
6
+ import logging
7
+ from typing import List, Dict, Optional
8
+ from sentence_transformers import SentenceTransformer
9
+ import numpy as np
10
+ from sklearn.metrics.pairwise import cosine_similarity
11
+
12
+ logger = logging.getLogger("chatbot.events")
13
+
14
+ class EventService:
15
+ def __init__(self, backend_url: str, model: SentenceTransformer):
16
+ self.backend_url = backend_url
17
+ self.model = model
18
+ self.events_cache = []
19
+ self.events_embeddings = None
20
+
21
+ def fetch_events(self) -> List[Dict]:
22
+ """Fetch all approved public events from backend"""
23
+ try:
24
+ response = requests.get(f"{self.backend_url}/api/events", timeout=5)
25
+ if response.status_code == 200:
26
+ data = response.json()
27
+ self.events_cache = data.get("data", {}).get("events", [])
28
+ logger.info(f"Fetched {len(self.events_cache)} events from backend")
29
+
30
+ # Pre-compute embeddings for all events
31
+ self._compute_event_embeddings()
32
+ return self.events_cache
33
+ else:
34
+ logger.error(f"Failed to fetch events: {response.status_code}")
35
+ return []
36
+ except Exception as e:
37
+ logger.error(f"Error fetching events: {e}")
38
+ return []
39
+
40
+ def _compute_event_embeddings(self):
41
+ """Compute embeddings for all events"""
42
+ if not self.events_cache:
43
+ return
44
+
45
+ event_texts = []
46
+ for event in self.events_cache:
47
+ # Combine title, description, and tags for better matching
48
+ text = f"{event.get('title', '')} {event.get('description', '')} {' '.join(event.get('tags', []))}"
49
+ event_texts.append(text)
50
+
51
+ self.events_embeddings = self.model.encode(event_texts, convert_to_tensor=False)
52
+ logger.info(f"Computed embeddings for {len(event_texts)} events")
53
+
54
+ def search_events(self, query: str, top_k: int = 5) -> List[Dict]:
55
+ """Search events using semantic similarity"""
56
+ if not self.events_cache or self.events_embeddings is None:
57
+ self.fetch_events()
58
+
59
+ if not self.events_cache:
60
+ logger.warning("No events available in cache")
61
+ return []
62
+
63
+ # Encode user query
64
+ query_embedding = self.model.encode([query], convert_to_tensor=False)
65
+
66
+ # Calculate cosine similarity
67
+ similarities = cosine_similarity(query_embedding, self.events_embeddings)[0]
68
+
69
+ # Log similarity scores for debugging
70
+ logger.info(f"Query: {query}")
71
+ logger.info(f"Similarity scores: min={similarities.min():.3f}, max={similarities.max():.3f}, mean={similarities.mean():.3f}")
72
+
73
+ # Get top k indices
74
+ top_indices = np.argsort(similarities)[::-1][:top_k]
75
+
76
+ # Filter events with similarity > threshold (lowered to 0.15 for better recall)
77
+ results = []
78
+ for idx in top_indices:
79
+ score = similarities[idx]
80
+ if score > 0.15: # Lowered threshold
81
+ event = self.events_cache[idx].copy()
82
+ event['similarity_score'] = float(score)
83
+ results.append(event)
84
+ logger.info(f" Event '{event.get('title', 'Untitled')}' matched with score {score:.3f}")
85
+
86
+ logger.info(f"Found {len(results)} matching events for query: {query}")
87
+ return results
88
+
89
+ def format_event_response(self, events: List[Dict]) -> str:
90
+ """Format events into a conversational response"""
91
+ if not events:
92
+ return "Sorry, I couldn't find any events matching your query. Try searching for something like 'hackathon', 'AI workshop', or 'coding competition'."
93
+
94
+ response = f"I found {len(events)} event(s) for you:\n\n"
95
+
96
+ for i, event in enumerate(events, 1):
97
+ title = event.get('title', 'Untitled Event')
98
+ date = event.get('date', 'TBA')[:10] if event.get('date') else 'TBA'
99
+ description = event.get('description', '')
100
+
101
+ # Truncate description
102
+ if len(description) > 100:
103
+ description = description[:97] + "..."
104
+
105
+ response += f"{i}. **{title}**\n"
106
+ response += f" 📅 Date: {date}\n"
107
+
108
+ if description:
109
+ response += f" 📝 {description}\n"
110
+
111
+ # Add website link if available
112
+ if event.get('socialLinks', {}).get('website'):
113
+ response += f" 🔗 [More Info]({event['socialLinks']['website']})\n"
114
+
115
+ response += "\n"
116
+
117
+ return response.strip()
faq.json ADDED
@@ -0,0 +1,373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "question": "How do I register for an event?",
4
+ "answer": "Visit the Events section, select your event, and click 'Register.' Complete the required details to finish registration."
5
+ },
6
+ {
7
+ "question": "How do I sign up for CampVerse?",
8
+ "answer": "Welcome! To sign up, just click the 'Register' button on our homepage and fill in your details. We're excited to have you join our community!"
9
+ },
10
+ {
11
+ "question": "Is CampVerse free to use?",
12
+ "answer": "Yes! CampVerse is free for all users. Some events may have entry fees, but browsing and joining the platform is always free."
13
+ },
14
+ {
15
+ "question": "Can I get help if I'm stuck?",
16
+ "answer": "Absolutely! If you ever need help, just reach out via our Support page or chat with us here. We're always happy to assist you!"
17
+ },
18
+ {
19
+ "question": "What should I do if I can't find my certificate?",
20
+ "answer": "No worries! Certificates are usually available in your dashboard after the event. If you can't find yours, contact support and we'll help you out."
21
+ },
22
+ {
23
+ "question": "How do I change my password?",
24
+ "answer": "To change your password, go to your profile settings and select 'Change Password.' If you forgot your password, use the 'Forgot Password' link on the login page."
25
+ },
26
+ {
27
+ "question": "Can I participate if I'm new to coding?",
28
+ "answer": "Of course! CampVerse welcomes everyone, whether you're a beginner or an expert. Many events are designed for all skill levels."
29
+ },
30
+ {
31
+ "question": "How do I contact a team member?",
32
+ "answer": "You can message your team members directly from your dashboard or use the chat feature during events."
33
+ },
34
+ {
35
+ "question": "What happens after I register for an event?",
36
+ "answer": "After registering, you'll receive a confirmation email and see the event in your dashboard. We'll keep you updated with all the important details!"
37
+ },
38
+ {
39
+ "question": "Can I join more than one team?",
40
+ "answer": "You can only join one team per event, but you're welcome to participate in multiple events with different teams!"
41
+ },
42
+ {
43
+ "question": "What are the rules for the upcoming hackathon?",
44
+ "answer": "Rules are available on the event details page or in the official rulebook linked there."
45
+ },
46
+ {
47
+ "question": "When is the deadline for the coding competition?",
48
+ "answer": "Deadlines are listed on each event page under 'Important Dates.'"
49
+ },
50
+ {
51
+ "question": "Where can I find the results of the last event?",
52
+ "answer": "Results are posted on the Results page and sent to registered participants via email."
53
+ },
54
+ {
55
+ "question": "Who is eligible to participate?",
56
+ "answer": "Eligibility criteria are shown on each event’s details page."
57
+ },
58
+ {
59
+ "question": "How do I form a team?",
60
+ "answer": "You can invite users to join your team during registration or from your dashboard."
61
+ },
62
+ {
63
+ "question": "What are the prizes?",
64
+ "answer": "Prize details are available on the event page under 'Prizes.'"
65
+ },
66
+ {
67
+ "question": "How do I reset my password?",
68
+ "answer": "Go to the login page and click 'Forgot Password' to receive reset instructions."
69
+ },
70
+ {
71
+ "question": "How do I contact support?",
72
+ "answer": "Use the Support page or submit a ticket from your dashboard."
73
+ },
74
+ {
75
+ "question": "Can I edit my registration details?",
76
+ "answer": "Yes, you can update your registration from your dashboard before the event deadline."
77
+ },
78
+ {
79
+ "question": "How do I upload required documents?",
80
+ "answer": "Upload documents via the event registration form or your dashboard."
81
+ },
82
+ {
83
+ "question": "Where can I find event schedules?",
84
+ "answer": "Schedules are listed on each event’s details page."
85
+ },
86
+ {
87
+ "question": "How do I verify my participation?",
88
+ "answer": "Verification details are sent via email and shown on your dashboard after the event."
89
+ },
90
+ {
91
+ "question": "What is the process for certificate generation?",
92
+ "answer": "Certificates are generated after event completion and can be downloaded from your dashboard."
93
+ },
94
+ {
95
+ "question": "How do I report a problem or bug?",
96
+ "answer": "Use the Feedback or Support section to report issues."
97
+ },
98
+ {
99
+ "question": "How do I access the leaderboard?",
100
+ "answer": "The leaderboard is available on the Results or event details page."
101
+ },
102
+ {
103
+ "question": "Can I participate in multiple events?",
104
+ "answer": "Yes, you can register for multiple events if eligible."
105
+ },
106
+ {
107
+ "question": "How do I check my eligibility status?",
108
+ "answer": "Your eligibility status is displayed on your dashboard and event registration page."
109
+ },
110
+ {
111
+ "question": "How do I get notifications about upcoming events?",
112
+ "answer": "Enable notifications in your profile settings or check the Notifications section."
113
+ },
114
+ {
115
+ "question": "How do I use the platform’s storage service?",
116
+ "answer": "Refer to the Storage Service Guide in the documentation section."
117
+ },
118
+ {
119
+ "question": "How do I view my achievements?",
120
+ "answer": "Achievements are listed in your user profile and dashboard."
121
+ },
122
+ {
123
+ "question": "How do I update my profile information?",
124
+ "answer": "Go to your dashboard and select 'Edit Profile' to update your information."
125
+ },
126
+ {
127
+ "question": "How do I join as a host or institution?",
128
+ "answer": "Apply through the Host/Institution registration page and follow the instructions."
129
+ },
130
+ {
131
+ "question": "How do I access event analytics?",
132
+ "answer": "Event analytics are available to hosts and institutions on their dashboard."
133
+ },
134
+ {
135
+ "question": "How do I request a certificate re-issue?",
136
+ "answer": "Submit a request via the Support or Certificate section in your dashboard."
137
+ },
138
+ {
139
+ "question": "How do I view feedback for events?",
140
+ "answer": "Feedback is available on the event details page and your dashboard."
141
+ },
142
+ {
143
+ "question": "How do I manage notifications?",
144
+ "answer": "Notification settings can be managed from your profile page."
145
+ },
146
+ {
147
+ "question": "How do I access secure files?",
148
+ "answer": "Secure files are available to eligible users via the Secure Files section in your dashboard."
149
+ },
150
+ {
151
+ "question": "How do I check event participation logs?",
152
+ "answer": "Participation logs are available in your dashboard under 'Event Participation.'"
153
+ },
154
+ {
155
+ "question": "How do I get help with ML features?",
156
+ "answer": "Refer to the ML Integration documentation or contact support for assistance."
157
+ },
158
+ {
159
+ "question": "How do I use the API?",
160
+ "answer": "API documentation is available in the docs section."
161
+ },
162
+ {
163
+ "question": "How do I view or download certificates?",
164
+ "answer": "Certificates can be viewed and downloaded from your dashboard after event completion."
165
+ },
166
+ {
167
+ "question": "How do I check host eligibility status?",
168
+ "answer": "Host eligibility status is shown on the host dashboard and event registration page."
169
+ },
170
+ {
171
+ "question": "How do I migrate my account or data?",
172
+ "answer": "Migration instructions are available in the documentation or contact support for help."
173
+ },
174
+ {
175
+ "question": "How do I access business analytics?",
176
+ "answer": "Business analytics are available to authorized users in the analytics dashboard."
177
+ },
178
+ {
179
+ "question": "How do I validate event modules?",
180
+ "answer": "Use the validation scripts provided in the scripts folder or contact support."
181
+ },
182
+ {
183
+ "question": "How do I get started as a new user?",
184
+ "answer": "Check the Getting Started guide in the documentation and follow onboarding steps."
185
+ },
186
+ {
187
+ "question": "How do I access the development approach?",
188
+ "answer": "Development approach details are available in the DEVELOPMENT_APPROACH.md file."
189
+ },
190
+ {
191
+ "question": "How do I check API endpoints?",
192
+ "answer": "API endpoints are documented in the swagger documentation and docs section."
193
+ },
194
+ {
195
+ "question": "How do I use socket features?",
196
+ "answer": "Refer to the socketClient.js example in the examples folder."
197
+ },
198
+ {
199
+ "question": "How do I check system status or downtime?",
200
+ "answer": "System status updates are posted in the Notifications section and via email."
201
+ },
202
+ {
203
+ "question": "How do I access the platform from mobile?",
204
+ "answer": "The platform is mobile-friendly and can be accessed via any browser."
205
+ },
206
+ {
207
+ "question": "How do I get help with frontend issues?",
208
+ "answer": "Refer to the Frontend TODO and error documentation or contact support."
209
+ },
210
+ {
211
+ "question": "How do I check my event certificates?",
212
+ "answer": "Event certificates are listed in your dashboard under 'Certificates.'"
213
+ },
214
+ {
215
+ "question": "How do I get updates about new features?",
216
+ "answer": "Updates are announced in the Notifications section and via email."
217
+ },
218
+ {
219
+ "question": "How do I access storage usage details?",
220
+ "answer": "Storage usage details are available in your dashboard under 'Storage.'"
221
+ },
222
+ {
223
+ "question": "How do I request event verification?",
224
+ "answer": "Submit a verification request from the event details page or your dashboard."
225
+ },
226
+ {
227
+ "question": "How do I access institution features?",
228
+ "answer": "Institution features are available to registered institutions via their dashboard."
229
+ },
230
+ {
231
+ "question": "How do I check notification history?",
232
+ "answer": "Notification history is available in your dashboard under 'Notifications.'"
233
+ },
234
+ {
235
+ "question": "How do I access support tickets?",
236
+ "answer": "Support tickets can be viewed and managed from your dashboard under 'Support.'"
237
+ }
238
+ ,
239
+ {
240
+ "question": "hi",
241
+ "answer": "Hi, I'm CampVerseBot! How can I help you today?"
242
+ },
243
+ {
244
+ "question": "hello",
245
+ "answer": "Hello! I'm CampVerseBot, here to assist you. What would you like to know?"
246
+ },
247
+ {
248
+ "question": "hey",
249
+ "answer": "Hey there! How can I help you at CampVerse today?"
250
+ },
251
+ {
252
+ "question": "good morning",
253
+ "answer": "Good morning! How can I help you today at CampVerse?"
254
+ },
255
+ {
256
+ "question": "good afternoon",
257
+ "answer": "Good afternoon! What can I do for you at CampVerse?"
258
+ },
259
+ {
260
+ "question": "good evening",
261
+ "answer": "Good evening! How can I assist you at CampVerse?"
262
+ },
263
+ {
264
+ "question": "bye",
265
+ "answer": "Goodbye! If you need anything else, just ask. Have a great day!"
266
+ },
267
+ {
268
+ "question": "goodbye",
269
+ "answer": "Goodbye! Thanks for visiting CampVerse. See you next time!"
270
+ },
271
+ {
272
+ "question": "see you",
273
+ "answer": "See you! If you have more questions, come back anytime."
274
+ }
275
+ ,
276
+ {
277
+ "question": "How do I create an account on CampVerse?",
278
+ "answer": "Click the 'Create Account' button on the homepage and fill in your details. You’ll receive a confirmation email to activate your account."
279
+ },
280
+ {
281
+ "question": "How do I verify my email address?",
282
+ "answer": "After signing up, check your inbox for a verification email from CampVerse. Click the link in the email to verify your address. If you don’t see it, check your spam folder or request a new verification email from your dashboard."
283
+ },
284
+ {
285
+ "question": "What should I do if I don’t receive a confirmation email?",
286
+ "answer": "First, check your spam or junk folder. If you still can’t find it, use the 'Resend Confirmation Email' option on the login page or contact support for help."
287
+ },
288
+ {
289
+ "question": "How do I browse and filter events?",
290
+ "answer": "Go to the Events section from the main menu. You can use filters to search by category, date, or institution to find events that interest you."
291
+ },
292
+ {
293
+ "question": "How do I join the CampVerse community?",
294
+ "answer": "Sign up with your college email and start participating in events, discussions, and feedback. You can also follow us on social media for updates."
295
+ },
296
+ {
297
+ "question": "How do I use the dashboard?",
298
+ "answer": "After logging in, your dashboard gives you access to your events, teams, certificates, notifications, and more. Use the sidebar to navigate different sections."
299
+ },
300
+ {
301
+ "question": "How do I contact support from the website?",
302
+ "answer": "Click the 'Support' or 'Help' link in the website footer or your dashboard to submit a ticket or chat with our support team."
303
+ },
304
+ {
305
+ "question": "What browsers and devices are supported?",
306
+ "answer": "CampVerse works best on the latest versions of Chrome, Firefox, Edge, and Safari. The platform is mobile-friendly and works on most smartphones and tablets."
307
+ },
308
+ {
309
+ "question": "How do I reset my password from the login page?",
310
+ "answer": "Click 'Forgot Password?' on the login page, enter your email, and follow the instructions sent to your inbox to reset your password."
311
+ },
312
+ {
313
+ "question": "How do I access event details and schedules?",
314
+ "answer": "Click on any event card to view its details, including schedule, rules, and prizes. Important dates are highlighted on the event page."
315
+ },
316
+ {
317
+ "question": "How do I use the Browse Events feature?",
318
+ "answer": "Use the 'Browse Events' button on the homepage or dashboard to see all upcoming and ongoing events. You can filter and sort events as needed."
319
+ },
320
+ {
321
+ "question": "How do I launch my own event on CampVerse?",
322
+ "answer": "If you’re an institution or host, log in to your dashboard and use the 'Create Event' option. Fill in the event details and submit for approval."
323
+ },
324
+ {
325
+ "question": "How do I access the institution dashboard?",
326
+ "answer": "Institution representatives can log in and access the institution dashboard from the main menu. Here you can manage events, view analytics, and more."
327
+ },
328
+ {
329
+ "question": "How do I update my profile or settings from the frontend?",
330
+ "answer": "Go to your dashboard, click on your profile icon, and select 'Edit Profile' to update your information, change your password, or manage notification settings."
331
+ },
332
+ {
333
+ "question": "Why can’t I see some events?",
334
+ "answer": "Some events may be restricted to certain colleges or require approval to join. Check the event’s eligibility criteria or contact support if you think there’s an error."
335
+ },
336
+ {
337
+ "question": "How do I know if an event is open to my college?",
338
+ "answer": "Each event page lists eligibility details. Look for 'Open to All' or check if your college is listed in the eligible institutions."
339
+ },
340
+ {
341
+ "question": "How do I join a team for an event?",
342
+ "answer": "When registering for an event, you can create a new team or join an existing one if the event allows teams. Follow the prompts during registration."
343
+ },
344
+ {
345
+ "question": "How do I leave feedback for an event?",
346
+ "answer": "After the event, go to the event page or your dashboard and look for the 'Leave Feedback' option. Your feedback helps us improve!"
347
+ },
348
+ {
349
+ "question": "How do I report inappropriate content or users?",
350
+ "answer": "Use the 'Report' button on user profiles or event pages, or contact support directly. We take all reports seriously and will investigate promptly."
351
+ },
352
+ {
353
+ "question": "How do I stay safe while using CampVerse?",
354
+ "answer": "Never share your password or sensitive information. Use official communication channels and report any suspicious activity to support."
355
+ }
356
+ ,
357
+ {
358
+ "question": "How do I get verified as a host?",
359
+ "answer": "To get verified as a host, register your host account through the dedicated portal. Our team will review your details and may request additional documentation. Once approved, you’ll receive a verification badge and access to host features."
360
+ },
361
+ {
362
+ "question": "What documents are required for host verification?",
363
+ "answer": "Typically, you’ll need to provide a valid ID and official contact information. Specific requirements are listed during the registration process."
364
+ },
365
+ {
366
+ "question": "How long does host verification take?",
367
+ "answer": "Host verification usually takes 2-5 business days after submitting all required documents. You’ll be notified by email once your account is verified."
368
+ },
369
+ {
370
+ "question": "What are the benefits of being a verified host?",
371
+ "answer": "Verified hosts can create and manage events, access advanced analytics, and gain greater visibility on CampVerse. A verification badge also builds trust with participants."
372
+ }
373
+ ]
intent_classifier.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Intent Classification Service
3
+ Detects user intent: greeting, event_search, help, thanks, farewell, general_question
4
+ """
5
+ import re
6
+ import logging
7
+ from typing import Tuple
8
+
9
+ logger = logging.getLogger("chatbot.intent")
10
+
11
+ class IntentClassifier:
12
+ def __init__(self):
13
+ # Define intent patterns with priority order
14
+ self.intent_patterns = {
15
+ 'greeting': [
16
+ r'^(hi|hello|hey|good morning|good afternoon|good evening|greetings|hii|hiii|helllo)[\s!?.]*$',
17
+ r'\b(hi|hello|hey|good morning|good afternoon|good evening|greetings)\b',
18
+ ],
19
+ 'farewell': [
20
+ r'\b(bye|goodbye|see you|farewell|take care|good night)\b',
21
+ ],
22
+ 'thanks': [
23
+ r'\b(thank|thanks|appreciate|grateful|thx)\b',
24
+ ],
25
+ 'host_help': [
26
+ # Host-specific questions (check before event_search)
27
+ r'\b(register|create|host|organize|add|post|submit|upload)\b.{0,50}\b(my event|an event|event)\b',
28
+ r'\b(how to|how can i|how do i)\b.{0,50}\b(register|create|host|organize|add|post)\b.{0,50}\b(event)\b',
29
+ r'\b(host|organizer|organiser)\b',
30
+ ],
31
+ 'event_search': [
32
+ # Direct event queries (search/find only)
33
+ r'\b(show|find|search|list|get|display|tell|give|want|need|looking for)\b.{0,50}\b(event|hackathon|workshop|competition|seminar|webinar|conference|meetup|contest|fest|festival)\b',
34
+ # Time-based queries
35
+ r'\b(upcoming|today|tomorrow|this week|this month|next|future|soon|latest|recent)\b.{0,50}\b(event|hackathon|workshop)\b',
36
+ # Location-based queries
37
+ r'\b(at|in|near|on)\b.{0,50}\b(campus|college|university|cuj|ccpc)\b',
38
+ # Category-based
39
+ r'\b(ai|ml|tech|coding|programming|software|web|mobile|data|science)\b.{0,50}\b(event|hackathon|workshop)\b',
40
+ # Simple keywords
41
+ r'^(event|hackathon|workshop|competition|seminar|webinar|conference|meetup)s?\s*$',
42
+ ],
43
+ 'help': [
44
+ r'\b(help|support|assist|guide|what can you do|how does)\b',
45
+ ],
46
+ }
47
+
48
+ def classify(self, text: str) -> Tuple[str, float]:
49
+ """
50
+ Classify user intent from text
51
+ Returns: (intent, confidence)
52
+ Priority: greeting/farewell/thanks > event_search > help > general_question
53
+ """
54
+ text_lower = text.lower().strip()
55
+
56
+ # Priority 1: Check for exact greetings (single word)
57
+ if text_lower in ['hi', 'hello', 'hey', 'hii', 'hiii', 'helllo', 'good morning', 'good afternoon', 'good evening']:
58
+ logger.info(f"Detected intent: greeting for text: {text}")
59
+ return 'greeting', 0.95
60
+
61
+ # Priority 2: Check for farewell and thanks
62
+ for intent in ['farewell', 'thanks']:
63
+ for pattern in self.intent_patterns[intent]:
64
+ if re.search(pattern, text_lower, re.IGNORECASE):
65
+ logger.info(f"Detected intent: {intent} for text: {text}")
66
+ return intent, 0.9
67
+
68
+ # Priority 3: Check for host_help (before event_search to avoid false positives)
69
+ for pattern in self.intent_patterns['host_help']:
70
+ if re.search(pattern, text_lower, re.IGNORECASE):
71
+ logger.info(f"Detected intent: host_help for text: {text}")
72
+ return 'host_help', 0.9
73
+
74
+ # Priority 4: Check for event_search
75
+ for pattern in self.intent_patterns['event_search']:
76
+ if re.search(pattern, text_lower, re.IGNORECASE):
77
+ logger.info(f"Detected intent: event_search for text: {text}")
78
+ return 'event_search', 0.85
79
+
80
+ # Priority 5: Check for help
81
+ for pattern in self.intent_patterns['help']:
82
+ if re.search(pattern, text_lower, re.IGNORECASE):
83
+ logger.info(f"Detected intent: help for text: {text}")
84
+ return 'help', 0.8
85
+
86
+ # Priority 5: Check for greeting (broader match)
87
+ for pattern in self.intent_patterns['greeting']:
88
+ if re.search(pattern, text_lower, re.IGNORECASE):
89
+ logger.info(f"Detected intent: greeting for text: {text}")
90
+ return 'greeting', 0.85
91
+
92
+ # Default to general question
93
+ logger.info(f"Detected intent: general_question for text: {text}")
94
+ return 'general_question', 0.5
95
+
96
+ def get_response_for_intent(self, intent: str) -> str:
97
+ """Get predefined response for specific intents"""
98
+ responses = {
99
+ 'greeting': "Hi! I'm CampVerseBot, here to help you discover events and answer your questions. You can ask me about upcoming hackathons, workshops, or any other events!",
100
+ 'farewell': "Goodbye! If you need anything else, just ask. Have a great day!",
101
+ 'thanks': "You're welcome! If you have more questions, feel free to ask.",
102
+ 'help': "I can help you with:\n\n• Finding events (hackathons, workshops, competitions)\n• Answering questions about CampVerse\n• Registration and account help\n\nJust ask me anything!",
103
+ 'host_help': "🎯 To register your event as a host:\n\n1️⃣ Sign Up/Login - Create an account or log in\n\n2️⃣ Go to Dashboard - Navigate to your host dashboard\n\n3️⃣ Create Event - Click 'Create Event' button\n\n4️⃣ Fill Details - Add title, description, date, venue, etc.\n\n5️⃣ Submit - Your event will be reviewed and published\n\n💡 Need more help? Check our Host Guide or contact support!",
104
+ }
105
+ return responses.get(intent, "")
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.115.0
2
+ uvicorn[standard]==0.32.0
3
+ sentence-transformers==3.3.1
4
+ faiss-cpu==1.9.0.post1
5
+ pandas==2.2.3
6
+ numpy==2.0.2
7
+ python-socketio==5.11.4
8
+ python-engineio==4.10.1
9
+ python-socketio[client]==5.11.4
10
+ requests==2.32.3
11
+ scikit-learn==1.5.2