Spaces:
Running
Running
| import os | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| load_dotenv(dotenv_path=Path(__file__).parent / "env") | |
| # ── Paths ───────────────────────────────────────────────────────────────── | |
| BASE_DIR = Path(__file__).parent | |
| INDEX_DIR = BASE_DIR / "faiss_index" | |
| INDEX_FILE = INDEX_DIR / "index.faiss" | |
| METADATA_FILE = INDEX_DIR / "metadata.json" | |
| # ── API keys ────────────────────────────────────────────────────────────── | |
| OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "") | |
| OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY", "") | |
| OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1" | |
| # ── Embedding & query expansion ────────────────────────────────────────── | |
| EMBEDDING_MODEL = "text-embedding-3-large" | |
| QUERY_EXPANSION_MODEL = "gpt-4o-mini" | |
| # ── Available LLM models ───────────────────────────────────────────────── | |
| AVAILABLE_MODELS = { | |
| "gpt-4o": { | |
| "label": "GPT-4o", | |
| "desc": "Flagship multimodal · best accuracy", | |
| "provider": "openai", | |
| "price_in": 2.50, | |
| "price_out": 10.00, | |
| }, | |
| "gpt-4o-mini": { | |
| "label": "GPT-4o mini", | |
| "desc": "Fast & affordable · great for simple tasks", | |
| "provider": "openai", | |
| "price_in": 0.15, | |
| "price_out": 0.60, | |
| }, | |
| "gpt-4.1-mini": { | |
| "label": "GPT-4.1 mini", | |
| "desc": "Latest mini · improved instruction-following", | |
| "provider": "openai", | |
| "price_in": 0.40, | |
| "price_out": 1.60, | |
| }, | |
| "gpt-5.4-mini": { | |
| "label": "GPT-5.4 mini", | |
| "desc": "Next-gen mini · advanced reasoning at low cost", | |
| "provider": "openai", | |
| "price_in": 0.25, | |
| "price_out": 1.00, | |
| }, | |
| "openai/gpt-4o-mini-2024-07-18": { | |
| "label": "GPT-4o OSS 120B", | |
| "desc": "Open-weight GPT-4o class · 120B params", | |
| "provider": "openrouter", | |
| "price_in": 0.15, | |
| "price_out": 0.60, | |
| }, | |
| "anthropic/claude-sonnet-4.6": { | |
| "label": "Claude Sonnet 4.6", | |
| "desc": "Anthropic · strong reasoning & long context", | |
| "provider": "openrouter", | |
| "price_in": 3.00, | |
| "price_out": 15.00, | |
| }, | |
| "moonshotai/kimi-k2": { | |
| "label": "Kimi K2", | |
| "desc": "Moonshot AI · efficient multilingual", | |
| "provider": "openrouter", | |
| "price_in": 0.60, | |
| "price_out": 2.50, | |
| }, | |
| "deepseek/deepseek-chat-v3-0324": { | |
| "label": "DeepSeek V3 Flash", | |
| "desc": "DeepSeek · ultra-low cost, strong reasoning", | |
| "provider": "openrouter", | |
| "price_in": 0.14, | |
| "price_out": 0.28, | |
| }, | |
| "google/gemini-2.0-flash-001": { | |
| "label": "Gemini 2.0 Flash", | |
| "desc": "Google · fast multimodal, 1M context window", | |
| "provider": "openrouter", | |
| "price_in": 0.10, | |
| "price_out": 0.40, | |
| }, | |
| "qwen/qwen3-235b-a22b": { | |
| "label": "Qwen3 235B", | |
| "desc": "Alibaba · massive MoE, hybrid thinking mode", | |
| "provider": "openrouter", | |
| "price_in": 0.13, | |
| "price_out": 0.40, | |
| }, | |
| "meta-llama/llama-4-maverick": { | |
| "label": "Llama 4 Maverick", | |
| "desc": "Meta · mixture-of-experts, best open-weight", | |
| "provider": "openrouter", | |
| "price_in": 0.20, | |
| "price_out": 0.60, | |
| }, | |
| } | |
| DEFAULT_MODEL = "gpt-4o-mini" | |
| # ── Retrieval tuning ───────────────────────────────────────────────────── | |
| TOP_K_VECTOR = 15 | |
| TOP_K_BM25 = 15 | |
| TOP_K_FINAL = 5 | |
| MIN_RETRIEVAL_SCORE = 0.25 | |
| # ── Generation tuning ──────────────────────────────────────────────────── | |
| TEMPERATURE = 0.2 | |
| MAX_RESPONSE_TOKENS = 800 | |
| # ── Request limits ──────────────────────────────────────────────────────── | |
| MAX_MESSAGE_LENGTH = 2_000 | |
| MAX_MESSAGES_PER_REQ = 50 | |
| MAX_HISTORY_MESSAGES = 8 | |
| # ── System prompts ──────────────────────────────────────────────────────── | |
| SYSTEM_EN = """\ | |
| You are KASITBot, the official academic assistant for KASIT \ | |
| (King Abdullah II School of Information Technology) at the University of Jordan. | |
| Your role: | |
| - Help students with courses, exams, fees, graduation requirements, office hours, \ | |
| scholarships (makruma), academic regulations, study plans, and faculty contacts. | |
| - Answer ONLY from the provided context documents. Do NOT invent, guess, or fabricate \ | |
| any information such as dates, numbers, names, fees, or schedules. | |
| - If the context does not contain the answer, say clearly: \ | |
| "I don't have this information in my current documents. Please check with the KASIT \ | |
| administration or visit the official University of Jordan website." | |
| - Never hallucinate course codes, professor names, exam dates, fee amounts, or any factual data. | |
| - When listing information (courses, schedules, fees), present it in a clear, structured format \ | |
| using tables or bullet points. | |
| - Reply in the same language the student used. If they write in Arabic, respond in Arabic. \ | |
| If in English, respond in English. | |
| - Be concise, accurate, and helpful. Students depend on you for correct academic guidance.\ | |
| """ | |
| SYSTEM_AR = """\ | |
| أنت كاسيت بوت، المساعد الأكاديمي الرسمي لكلية الملك عبدالله الثاني لتكنولوجيا المعلومات \ | |
| (KASIT) في الجامعة الأردنية. | |
| دورك: | |
| - مساعدة الطلاب في المساقات والامتحانات والرسوم ومتطلبات التخرج وساعات المكتب \ | |
| والمكرمات والأنظمة الأكاديمية والخطط الدراسية والتواصل مع أعضاء هيئة التدريس. | |
| - أجب فقط من الوثائق والسياق المتاح لك. لا تخترع أو تتوقع أو تُلفّق أي معلومات \ | |
| مثل التواريخ أو الأرقام أو الأسماء أو الرسوم أو الجداول. | |
| - إذا لم يحتوِ السياق على الإجابة، قل بوضوح: \ | |
| "لا تتوفر لدي هذه المعلومة في الوثائق الحالية. يرجى مراجعة إدارة كلية كاسيت \ | |
| أو زيارة الموقع الرسمي للجامعة الأردنية." | |
| - لا تختلق أبداً أرقام مساقات أو أسماء أساتذة أو تواريخ امتحانات أو مبالغ رسوم \ | |
| أو أي بيانات واقعية. | |
| - عند عرض المعلومات (مساقات، جداول، رسوم)، قدمها بشكل منظم وواضح \ | |
| باستخدام جداول أو نقاط. | |
| - أجب بنفس اللغة التي يستخدمها الطالب. | |
| - كن موجزاً ودقيقاً ومفيداً. الطلاب يعتمدون عليك للحصول على إرشاد أكاديمي صحيح.\ | |
| """ | |
| # ── Student portal tool definitions ─────────────────────────────────────── | |
| PORTAL_TOOLS = [ | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_student_profile", | |
| "description": ( | |
| "Retrieve the registered student's full profile: name, student ID, email, " | |
| "GPA, major, year, semester, academic year, enrollment status, total enrolled " | |
| "courses, and total credit hours this semester. Call this whenever the user " | |
| "asks about who they are, their GPA, their ID, their email, their major, or " | |
| "a general summary of their registration." | |
| ), | |
| "parameters": {"type": "object", "properties": {}, "required": []}, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_enrolled_courses", | |
| "description": ( | |
| "Return the list of courses the student is currently enrolled in this semester, " | |
| "including course number, name, instructor, days, times, room, credits, and category. " | |
| "Call this when the user asks about their current courses, schedule, what they are " | |
| "taking, credit hours, or any specific enrolled course detail." | |
| ), | |
| "parameters": {"type": "object", "properties": {}, "required": []}, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_available_courses", | |
| "description": ( | |
| "Return all courses currently available for the student to add/register, " | |
| "including seats available, prerequisites, instructor, and schedule. " | |
| "Call this when the user asks what courses they can add, available courses, " | |
| "or courses offered this semester that they are NOT enrolled in." | |
| ), | |
| "parameters": {"type": "object", "properties": {}, "required": []}, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_schedule", | |
| "description": ( | |
| "Return the student's full weekly schedule with all enrolled courses ordered by time. " | |
| "Call this when the user asks for their schedule, timetable, or wants to print/download " | |
| "their course schedule." | |
| ), | |
| "parameters": {"type": "object", "properties": {}, "required": []}, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "enroll_course", | |
| "description": ( | |
| "Enroll (add/register) the student into a course. Call this when the user explicitly " | |
| "asks to add, enroll in, register for, or sign up for a course. " | |
| "You must provide the exact course_number. If the user gives a course name instead, " | |
| "first call get_available_courses to find the matching course_number." | |
| ), | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "course_number": { | |
| "type": "string", | |
| "description": "The exact course code/number (e.g., 'CS5502', '1915471')", | |
| } | |
| }, | |
| "required": ["course_number"], | |
| }, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "drop_course", | |
| "description": ( | |
| "Drop (withdraw/remove) the student from an enrolled course. Call this when the user " | |
| "explicitly asks to drop, remove, withdraw from, or delete a course. " | |
| "You must provide the exact course_number. If the user gives a course name instead, " | |
| "first call get_enrolled_courses to find the matching course_number." | |
| ), | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "course_number": { | |
| "type": "string", | |
| "description": "The exact course code/number to drop (e.g., '1915471')", | |
| } | |
| }, | |
| "required": ["course_number"], | |
| }, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "update_gpa", | |
| "description": ( | |
| "Update the student's GPA to a new value. Only call this when the user explicitly " | |
| "asks to update, change, or set their GPA. The GPA must be between 0.0 and 4.0." | |
| ), | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "gpa": { | |
| "type": "number", | |
| "description": "The new GPA value, must be between 0.0 and 4.0", | |
| } | |
| }, | |
| "required": ["gpa"], | |
| }, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_semester_history", | |
| "description": ( | |
| "Return the student's complete semester-by-semester academic history: " | |
| "every semester's GPA, credit hours taken, cumulative GPA, cumulative credits, " | |
| "year level, and registration status — going back to the first semester. " | |
| "Call this for ANY question about past or historical GPA, a specific semester's " | |
| "performance, grade trends, cumulative credits, academic level, or year-by-year progress." | |
| ), | |
| "parameters": {"type": "object", "properties": {}, "required": []}, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_absence_records", | |
| "description": ( | |
| "Return the student's absence count for each currently enrolled course, " | |
| "including warning flags for courses approaching the 25% absence limit. " | |
| "Call this for ANY question about absences, attendance, missed classes, " | |
| "or risk of being barred from exams." | |
| ), | |
| "parameters": {"type": "object", "properties": {}, "required": []}, | |
| }, | |
| }, | |
| ] | |