forked from VanshKing30/codenest
-
Notifications
You must be signed in to change notification settings - Fork 4
Integrated context-aware chatbot #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
i-am-that-guy
wants to merge
3
commits into
main
Choose a base branch
from
Chatbot
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| const formatHistory = (history: { from: string; text: string }[] = []) => | ||
| history | ||
| .map((m) => `${m.from === "user" ? "User" : "Assistant"}: ${m.text}`) | ||
| .join("\n"); | ||
|
|
||
| export function buildPrompt({ | ||
| path, | ||
| ragData, | ||
| userAnswer, | ||
| questionContext, | ||
| history = [], | ||
| }: { | ||
| path: string; | ||
| ragData: any; | ||
| userAnswer: string; | ||
| questionContext?: any; | ||
| history?: { from: string; text: string }[]; | ||
| }) { | ||
aaryagodbole marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const baseRole = ` | ||
| You are Cortex, an intelligent AI analyst for "Call of Code". | ||
| STRICT LIMITATION: Your knowledge is limited EXCLUSIVELY to DSA and Interview Experiences. | ||
|
|
||
| 🎯 YOUR GOALS: | ||
| 1. If user says hi or hello, greet them back briefly and ask how you can assist in DSA/Interview prep. | ||
| 2. Provide accurate, concise, and relevant answers ONLY related to DSA problems or interview experiences. | ||
| 3. Politely refuse to answer anything outside DSA/Interviews with the Refusal Message below. | ||
|
|
||
| 💡 SPECIAL INSTRUCTIONS BASED ON CONTEXT: | ||
| 1. DSA HELP (3-Step Method): | ||
| - Start with a **simple hint** only. | ||
| - If user asks for solution (e.g., "give code", "solve it"), provide: (a) Brute-force logic + code, (b) Optimal solution + code. | ||
| - Suggest 2-3 similar practice problems from LeetCode/GFG/CodeChef. | ||
| 2. CAREER QUESTIONS: Define the role, list skills, give a step-by-step roadmap, and suggest learning platforms. | ||
| 3. INTERVIEW ANALYSIS: Provide direct answers based on stories. DO NOT give hints for interview data queries. | ||
|
|
||
| RULES: | ||
| - If the query is NOT about DSA/Interviews, use the Refusal Message: "I am Cortex, specialized only in DSA and Interview analysis. Let's stay focused on your preparation!" | ||
| - Do NOT start a mock interview. Do NOT act as Alex. | ||
| - Use Markdown (bold, headers, code blocks) and emojis 🚀. | ||
| `; | ||
|
|
||
| console.log("🧠 QUESTION CONTEXT IN chatBrain 👉", questionContext); | ||
aaryagodbole marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // --- CASE 1: DSA TOPIC ONLY --- | ||
| if (questionContext?.type === "DSA" && questionContext.isTopicOnly) { | ||
| const questionsList = ragData?.relatedQuestions | ||
| ? ragData.relatedQuestions.map((q: any) => `- ${q.title}`).join("\n") | ||
| : "No questions listed for this topic yet."; | ||
|
|
||
| return ` | ||
| ${baseRole} | ||
| User is browsing: ${questionContext.topicTitle} | ||
| Available Questions in this topic: | ||
| ${questionsList} | ||
|
|
||
| Instructions: | ||
| - Briefly explain the importance of ${questionContext.topicTitle} in interviews. | ||
| - If user asks what to solve, suggest questions from the list above. | ||
|
|
||
| User Query: ${userAnswer} | ||
| `; | ||
| } | ||
|
|
||
| // --- CASE 2: SPECIFIC DSA QUESTION --- | ||
| if (questionContext?.type === "DSA" && questionContext.questionId) { | ||
| const context = ragData ? `QUESTION: ${ragData.question}\nCONCEPT: ${ragData.concept}` : "No specific details available."; | ||
|
|
||
| return ` | ||
| ${baseRole} | ||
| Conversation so far: | ||
| ${formatHistory(history)} | ||
|
|
||
| CURRENT QUESTION: ${questionContext.questionName} (${questionContext.topicTitle}) | ||
| ${context} | ||
|
|
||
| USER ANSWER / CODE: | ||
| ${userAnswer} | ||
|
|
||
| Instructions: | ||
| - Give ONLY a hint first. | ||
| - Point out logical mistakes. | ||
| `; | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // --- CASE 3: INTERVIEW ANALYST (COLLECTION) --- | ||
| if (questionContext?.type === "INTERVIEW_COLLECTION") { | ||
| // Check if ragData exists and has items | ||
| const allExperiences = (Array.isArray(ragData) && ragData.length > 0) | ||
| ? ragData.slice(0, 10).map((exp: any) => // Top 10 for performance | ||
| `Student: ${exp.member?.name || "User"} | Company: ${exp.company} | Verdict: ${exp.verdict} | Summary: ${exp.role}` | ||
| ).join("\n") | ||
| : "No specific interview stories found in the database."; | ||
|
|
||
| return ` | ||
| ${baseRole} | ||
| CONTEXT: The user is looking at the Interview Experiences page. | ||
| DATABASE SUMMARY (Last few stories): | ||
| ${allExperiences} | ||
|
|
||
| User Question: ${userAnswer} | ||
|
|
||
| Instructions: | ||
| - Analyze the common patterns in the stories provided. | ||
| - Identify common mistakes leading to "Rejected" verdicts. | ||
| - Determine which companies focused more on DSA. | ||
| - If they ask for details of a specific person, tell them to click on that card for a deep-dive analysis. | ||
| `; | ||
| } | ||
|
|
||
| // --- CASE 4: SINGLE INTERVIEW EXPERIENCE --- | ||
| if (questionContext?.type === "INTERVIEW_EXPERIENCE") { | ||
| const current = ragData?.currentInterview || questionContext; | ||
| const content = ragData?.currentInterview?.content || "Story content loading..."; | ||
| const studentName = current.member?.name || current.studentName || "the candidate"; | ||
|
|
||
| return ` | ||
| ${baseRole} | ||
| CONTEXT: Interview for ${current.company}. | ||
| CANDIDATE: ${studentName} | VERDICT: ${current.verdict} | ||
| DATA: """${content}""" | ||
|
|
||
| INSTRUCTIONS: | ||
| 1. If the user says "hi" or "hello", greet them professionally and ask what they want to know specifically. | ||
| 2. Provide the FULL ANALYSIS ONLY if the user asks a specific question (e.g., "what rounds?", "questions?", "give analysis"). | ||
| 3. Use this format for analysis: | ||
| 🔍 **Analysis: ${current.company} Journey** | ||
| - **The Process**: ... | ||
| - **Technical Deep-Dive**: ... | ||
| - **The Verdict Factor**: ... | ||
|
|
||
| User Query: ${userAnswer} | ||
| `; | ||
| } | ||
aaryagodbole marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // --- CASE 5: DEFAULT FALLBACK --- | ||
| return ` | ||
| ${baseRole} | ||
| Conversation so far: | ||
| ${formatHistory(history)} | ||
| User message: ${userAnswer} | ||
| `; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| import { Request, Response } from "express"; | ||
| import { fetchRAGContext } from "../services/retrival"; | ||
| import { buildPrompt } from "../ai/chatBrain"; | ||
| import { geminiModel } from "../services/ai"; | ||
|
|
||
| export async function chatController(req: Request, res: Response) { | ||
| try { | ||
| const { | ||
| path, | ||
| userAnswer, | ||
| questionContext, | ||
| history = [], // Added default value | ||
| } = req.body; | ||
aaryagodbole marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Fetch RAG data | ||
| const ragData = await fetchRAGContext(questionContext); | ||
|
|
||
|
|
||
| if (ragData) { | ||
| console.log(` Context Loaded: ${ragData.company || ragData.topicTitle || 'General'}`); | ||
| } | ||
|
|
||
| const prompt = buildPrompt({ | ||
| path, | ||
| ragData, | ||
| userAnswer, | ||
| questionContext, | ||
| history, | ||
| }); | ||
|
|
||
| // Call Gemini | ||
| const chat = geminiModel.startChat({ | ||
| history: [], | ||
| }); | ||
|
|
||
| try { | ||
| const result = await chat.sendMessage(prompt); | ||
| const reply = result.response.text(); | ||
| return res.json({ reply }); // Explicit return | ||
| } catch (aiError: any) { | ||
| // ⚠️ Handle Gemini Specific Overload (503) | ||
| if (aiError.status === 503 || aiError.message?.includes("503")) { | ||
| return res.status(503).json({ | ||
| reply: "Google's AI servers are a bit busy 🧠⚡. Please wait 5-10 seconds and try again!", | ||
| }); | ||
| } | ||
| throw aiError; // Pass to main catch | ||
| } | ||
|
|
||
| } catch (error) { | ||
| console.error("🚨 Chat Controller Error:", error); | ||
| const err = error as Error; | ||
|
|
||
| res.status(500).json({ | ||
| reply: "Cortex encountered an issue. Let's try that again in a moment.", | ||
| error: process.env.NODE_ENV === 'development' ? err.message : undefined // Hide technical error in production | ||
| }); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import { Router } from "express"; | ||
| import { chatController } from "../controllers/chatController"; | ||
|
|
||
| const chatRouter = Router(); | ||
|
|
||
| chatRouter.post("/", chatController); | ||
|
|
||
| export default chatRouter; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { GoogleGenerativeAI } from "@google/generative-ai"; | ||
|
|
||
| const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!); | ||
|
|
||
| export const geminiModel = genAI.getGenerativeModel({ | ||
| model: "gemini-2.5-flash", | ||
| }); | ||
aaryagodbole marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.