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 2 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
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,134 @@ | ||
| 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.
|
||
| 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. 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.
|
||
|
|
||
| // --- CASE 1: DSA TOPIC ONLY --- | ||
| if (questionContext?.type === "DSA" && questionContext.isTopicOnly) { | ||
| return ` | ||
| ${baseRole} | ||
| User is currently browsing the topic: ${questionContext.topicTitle}. | ||
|
|
||
| Conversation so far: | ||
| ${formatHistory(history)} | ||
|
|
||
| Instructions: | ||
| - Provide a brief overview of ${questionContext.topicTitle}. | ||
| - Mention common interview patterns. | ||
|
|
||
| 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.
|
||
|
|
||
| // --- CASE 3: INTERVIEW ANALYST (COLLECTION) --- | ||
| if (questionContext?.type === "INTERVIEW_COLLECTION") { | ||
| // 🛡️ SAFETY CHECK: Ensure ragData is an array before mapping | ||
| const allExperiences = Array.isArray(ragData) | ||
| ? ragData.map((exp: any) => ` | ||
| Company: ${exp.company} | ||
| Verdict: ${exp.verdict} | ||
| Experience: ${exp.content} | ||
| `).join("\n---\n") | ||
| : "No interview data available to analyze."; | ||
|
|
||
| return ` | ||
| ${baseRole} | ||
| You are an Interview Analyst. You have access to ${questionContext.count || 0} interview stories. | ||
|
|
||
| DATASET: | ||
| ${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. | ||
| `; | ||
| } | ||
|
|
||
| // --- CASE 4: SINGLE INTERVIEW EXPERIENCE --- | ||
| // chatBrain.ts update for CASE 4 | ||
| // --- CASE 4: SINGLE INTERVIEW EXPERIENCE --- | ||
| if (questionContext?.type === "INTERVIEW_EXPERIENCE") { | ||
| const interview = ragData || questionContext; | ||
| // Added a check to see if content is actually there | ||
| const content = ragData?.content || "No database content found. Request might have failed."; | ||
|
|
||
| // LOGGING: Check your backend terminal to see what is being packed into the prompt | ||
| console.log("🛠️ PROMPT BUILDING WITH CONTENT:", content.substring(0, 50) + "..."); | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| return ` | ||
| ${baseRole} | ||
| CURRENT CONTEXT: | ||
| Company: ${interview.company} | ||
| Role: ${interview.role} | ||
| Verdict: ${interview.verdict} | ||
| Full Experience: ${content} | ||
|
|
||
| User Query: ${userAnswer} | ||
| `; | ||
| } | ||
|
aaryagodbole marked this conversation as resolved.
aaryagodbole marked this conversation as 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,55 @@ | ||
| 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, | ||
| } = req.body; | ||
|
aaryagodbole marked this conversation as resolved.
|
||
|
|
||
|
|
||
| // Fetch RAG data | ||
| const ragData = await fetchRAGContext(questionContext); | ||
| if (ragData) { | ||
| console.log("✅ DATA FOUND. Company:", ragData.company || "N/A"); | ||
| console.log("📝 CONTENT PREVIEW:", ragData.content?.substring(0, 50) + "..."); | ||
| } else { | ||
| console.log("🔍 DATA TO AI: No record found."); | ||
| } | ||
|
|
||
| const prompt = buildPrompt({ | ||
| path, | ||
| ragData, | ||
| userAnswer, | ||
| questionContext, | ||
| history, | ||
| }); | ||
|
|
||
| // Call Gemini | ||
| const chat = geminiModel.startChat({ | ||
| history: [], // History handled in prompt | ||
| }); | ||
|
|
||
| const result = await chat.sendMessage(prompt); // prompt has all context | ||
| const reply = result.response.text(); | ||
|
|
||
| // Send Response | ||
| res.json({ reply }); | ||
|
|
||
| } catch (error) { | ||
| console.error("Chat Controller Error:", error); | ||
|
|
||
| const err = error as Error; | ||
|
|
||
|
|
||
| res.status(500).json({ | ||
| reply: "Cortex is having trouble accessing the context right now. Please try again.", | ||
| error: err.message | ||
| }); | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
| } | ||
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.
|
||
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,58 @@ | ||
| import fetch from "node-fetch"; | ||
|
|
||
| export async function fetchRAGContext(questionContext?: any) { | ||
| if (!questionContext) return null; | ||
|
|
||
| try { | ||
| // --- 1. DSA LOGIC --- | ||
| if (questionContext.type === "DSA") { | ||
| if (questionContext.questionId) { | ||
| const res = await fetch(`${process.env.API_URL}/dsa/questions/${questionContext.questionId}`); | ||
| return res.ok ? await res.json() : null; | ||
| } | ||
|
|
||
| if (questionContext.isTopicOnly && questionContext.topicId) { | ||
| const res = await fetch(`${process.env.API_URL}/topics/${questionContext.topicId}`); | ||
| return res.ok ? await res.json() : null; | ||
| } | ||
| } | ||
|
|
||
| // --- 2. INTERVIEW COLLECTION (Analysis Mode) --- | ||
|
|
||
| if (questionContext.type === "INTERVIEW_COLLECTION") { | ||
| if (questionContext.interviewIds && questionContext.interviewIds.length > 0) { | ||
| const res = await fetch(`${process.env.API_URL}/interviews?ids=${questionContext.interviewIds.join(',')}`); | ||
| const data = await res.json() as any; | ||
| return Array.isArray(data) ? data : (data.interviews || []); | ||
| } | ||
|
aaryagodbole marked this conversation as resolved.
Outdated
|
||
|
|
||
| const res = await fetch(`${process.env.API_URL}/interviews/all`); | ||
| if (!res.ok) return []; | ||
| const data = await res.json() as any; | ||
| return Array.isArray(data) ? data : (data.interviews || []); | ||
| } | ||
|
|
||
|
|
||
| if (questionContext.type === "INTERVIEW_EXPERIENCE") { | ||
| const res = await fetch(`http://localhost:3000/api/v1/interviews/${questionContext.id}`); | ||
|
|
||
| if (res.ok) { | ||
| const json = await res.json() as any; | ||
|
|
||
| // Extract the actual data (handling potential API wrappers) | ||
| const actualData = json.data || json.interview || json; | ||
|
|
||
| console.log("SUCCESS: Data found for", actualData.company); | ||
| return { ...questionContext, ...actualData }; | ||
| } | ||
| console.log("Fetch failed. Status:", res.status); | ||
| return questionContext; | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| } catch (error) { | ||
| console.error("Error in RAG retrieval:", error); | ||
| return null; | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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.