Skip to content
Open
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
73 changes: 71 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,71 @@
# iitm-submission-odyssey
Submissions for IITM Odyssey Hackathon
# 📘 README: AI Assistant Skills for Online Course Platform

This assistant is designed to support students across various academic topics such as **Biology**, **Linguistics**, **Computer Science**, **Python Programming**, **Calculus**, and **Software Engineering**. It offers help in answering academic queries, providing logistics information for courses, and managing study schedules.

# Drive Link for Demo and ppt
https://drive.google.com/drive/folders/1w0c6QvOwNwAMBjCuIPPgDr5HPm1H3oLh?usp=drive_link
---

## 🔧 Skills Overview

### 1. `Get_questions`

**Purpose:**
Retrieve frequently asked questions from previous student logs for a specific course. This feature is locally hosted.

**Usage:**
- Used only when the query is about **logistics** (e.g., deadlines, grading, syllabus).
- Requires a `Course_name` field present in the user's request.
- Only the **main topic** from each FAQ is returned.

**Important Rules:**
- Do **not** use any other skill when using this.
- If `Course_name` is **missing**, reply:
> "The course name is not present in the article."
And provide the **list of available courses** directly.

---

### 2. `AddGoogleCalendarEvent`

We have created Operations feature called Add_gevent
**Purpose:**
Add academic events (like assignment deadlines, exam reminders, etc.) to a student’s calendar.

**Usage:**
- Automatically assumes the **Asia/Kolkata** timezone.
- Triggered when students ask to **add an event** (e.g., “remind me of the quiz tomorrow”).

---

### 3. `RAG`

**Purpose:**
Answer academic questions by retrieving information from course materials using **Retrieval-Augmented Generation**. The data is vectorized and saved in local storage. This feature is locally hosted.

**Usage:**
- First choice when the student asks a question on course content.
- Summarized responses must include:
- **Lecture number**
- **Week number**

---

### 4. `WebScrape`

**Purpose:**
Provide external context if `RAG` is **not sufficient** or **not relevant**.

**Usage:**
- Used only **if RAG fails** to provide an adequate or relevant answer.
- When summarizing, always include **relevant source links**.

---

## ✅ Assistant Behavior Summary

- **Primary Focus:** Academic support in biology, linguistics, CS, Python, calculus, software engineering.
- **Polite Redirection:** Gently guide students back to academic topics if the query goes off-track.
- **Course Logistics:** Use `Get_questions` with `Course_name`, and do not mix it with other skills.
- **Calendar Support:** Use `AddGoogleCalendarEvent` for event reminders (default to Asia/Kolkata).
- **Contextual Help:** Use `RAG` for academic queries and fall back to `WebScrape` if needed.
83 changes: 83 additions & 0 deletions locally_hosted_apis/devrev_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from flask import Flask, render_template, request, jsonify
import json
import sys
import os
from datetime import datetime
import requests


from rag_agent import token
from rag_agent import serverHandler

TAVILY_API_KEY = "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"
access_token = "ya29.a0AZYkNZhRCtH1m2Rhuo32QzLvKquNvgBtBj68a8T7L9rf-4CXOdNAAm8_ljcuaPvrHdW6lUg5pvz5pOsKwcdihuvScIsYmGDhbTjcAn5-lTac58tDTet73PVwDL2hZOcTWYTM-BAoLaze5nY5F3fKupdGd4Fb0VXtsumwLM-lPwaCgYKAUgSARMSFQHGX2MiSv-sR4oCvgtz0ZfmdKsIKg0177"

app = Flask(__name__)

server = serverHandler(vdb_path="updated_vectordb",TAVILY_API_KEY=TAVILY_API_KEY)

@app.route('/rag_message', methods=['POST'])
def rag_message():

try:
data = request.get_json()
token1 = token(data["username"],data["message"],data["course"])
final_token = server.handle_token_rag(token1)


generated_response = final_token.response
data["response"] = generated_response
return jsonify({"status": "success", "message": "Message saved", "response": generated_response}), 200

except Exception as e:
return jsonify({"error": "Error Generating Response","message":str(e)}), 500

@app.route('/web_message', methods=['POST'])
def web_message():

try:
data = request.get_json()
token1 = token(data["username"],data["message"],data["course"])
final_token = server.handle_token_web(token1)


generated_response = final_token.response
data["response"] = generated_response
return jsonify({"status": "success", "message": "Message saved", "response": generated_response}), 200

except Exception as e:
return jsonify({"error": "Error Generating Response","message":str(e)}), 500


@app.route('/add_event', methods=['POST'])
def add_event():
print("add_event")
url = 'https://www.googleapis.com/calendar/v3/calendars/primary/events'

headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
try:
data = request.get_json()
event_data = {
"summary": data["summary"],
"start": {
"dateTime": data["start_time"],
"timeZone": data["timezone"]
},
"end": {
"dateTime": data["end_time"],
"timeZone": data["timezone"]
}
}
print("event_data",event_data)
response = requests.post(url, headers=headers, json=event_data)

return jsonify({"status": "success", "message": "Event added successfully"}), 200
except Exception:
return jsonify({"status": "error", "message": "Failed to add event"}), 500


if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
72 changes: 72 additions & 0 deletions locally_hosted_apis/rag_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os
from tavily import TavilyClient
import chromadb
from chromadb.utils import embedding_functions


# Token class
class token:
def __init__(self,username,query,courseID):
self.courseID = courseID
self.query = query
self.response = None
self.username = username

class vectordbclass:
def __init__(self, path):
self.path = path
self.chroma_client = chromadb.PersistentClient(path=path)
self.embedding_fn = embedding_functions
self.sentence_transformer_ef = self.embedding_fn.SentenceTransformerEmbeddingFunction(model_name="all-mpnet-base-v2")
self.collection = self.chroma_client.get_or_create_collection(name=path, embedding_function=self.sentence_transformer_ef)

def query(self, query_text, n_results=3):
results = self.collection.query(query_texts=[query_text], n_results=n_results, include=['documents', 'metadatas'])
actual_results = min(n_results, len(results['documents'][0]) if results['documents'] else 0)
context = f'''The following are {actual_results} results from the vector database:\n'''

for i in range(actual_results):
context += '''\nResult {} Lecture No:{} Week:{} Course Name:{}\n Context: {}\n'''.format(
i+1,
results['metadatas'][0][i].get('lecture_no', 'N/A'),
results['metadatas'][0][i].get('week', 'N/A'),
results['metadatas'][0][i].get('courseID', 'N/A'),
results['documents'][0][i]
)
return context if actual_results > 0 else "No results found."

# RAG Agent class
class RAG_Agent:
def __init__(self,vectordb):
self.vectordb = vectordb

# Generating response based on the question
def generate_response(self,tok1):
context = self.vectordb.query(tok1.query,3)
tok1.response = context
return tok1

class Web_Agent:
def __init__(self,TAVILY_API_KEY):
self.web = TavilyClient(api_key=TAVILY_API_KEY)
# Generating response based on the question
def generate_response(self,tok1):
context= self.web.search(tok1.query, search_depth="basic")["results"][:3]
tok1.response = context
return tok1

# Server handler class
class serverHandler:
def __init__(self,vdb_path,TAVILY_API_KEY):
self.vectordb = vectordbclass(vdb_path)
self.TAVILY_API_KEY = TAVILY_API_KEY

def handle_token_rag(self,tok1):
new_model = RAG_Agent(self.vectordb)
final_token = new_model.generate_response(tok1)
return final_token

def handle_token_web(self,tok1):
new_model = Web_Agent(self.TAVILY_API_KEY)
final_token = new_model.generate_response(tok1)
return final_token
Loading