File size: 4,698 Bytes
52c281c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e99494
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os
from dotenv import load_dotenv
from google import genai
from google.genai import types
from pinecone import Pinecone

load_dotenv()

# Initialize Pinecone
pc = Pinecone(api_key=os.getenv("PINECONE_API_KEY"))
index = pc.Index("portfolio-chat")

# Initialize Google GenAI Client
client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))

# Constants
EMBEDDING_MODEL = "gemini-embedding-001"
LLM_MODEL = "gemini-2.5-flash-lite"
EMBEDDING_DIMENSION = 768

def get_embedding(text: str) -> list[float]:
    """Generate embedding for a given text using Gemini embedding model."""
    try:
        response = client.models.embed_content(
            model=EMBEDDING_MODEL,
            contents=text,
            config=types.EmbedContentConfig(
                output_dimensionality=EMBEDDING_DIMENSION
            )
        )
        return response.embeddings[0].values
    except Exception as e:
        print(f"Error generating embedding: {e}")
        return []

def get_rag_response(query: str) -> str:
    """
    RAG pipeline: embed query, retrieve context from Pinecone, generate response.
    """
    try:
        # Step 1: Embed the query
        query_embedding = get_embedding(query)
        if not query_embedding:
            return "I'm having a little trouble accessing my brain right now. Please try again!"

        # Step 2: Query Pinecone for top 5 matches
        results = index.query(
            vector=query_embedding,
            top_k=10,
            include_metadata=True
        )
        
        # Step 3: Extract context from matches
        context_chunks = []
        for match in results.matches:
            if match.metadata and "text" in match.metadata:
                context_chunks.append(match.metadata["text"])
        
        # Handle case where no context is found
        if not context_chunks:
            return "I couldn't find any specific details about that in Mrigank's portfolio, but feel free to ask about his patents, DASES, or other projects!"
        
        # Join chunks to create the context text
        context_text = "\n\n---\n\n".join(context_chunks)
        
        # Step 4: Construct the system prompt
        system_prompt = f"""You are the Advanced AI Assistant for **Mrigank Singh**, a Full Stack AI Developer and Innovator. 
        Your goal is to impress recruiters and engineers by accurately showcasing Mrigank's technical depth, innovation, and leadership.

        ### CORE INSTRUCTIONS:
        1. **Identity:** You are NOT Mrigank. You are his digital assistant. Refer to him as "Mrigank" or "he".
        2. **Tone:** Professional, confident, and technically precise. Sound like a Software Engineer, not a marketing brochure.
        3. **Formatting:** Use **Markdown** to make answers readable. 
           - Use **bold** for key technologies or metrics.
           - Use `bullet points` for lists (skills, projects).
           - Do not output large walls of text; break it up.
        4. **Source of Truth:** Answer ONLY based on the "CONTEXT" provided below. Do not make up facts. 
           - If the answer isn't in the context, say: "I don't have that specific detail, but I can tell you about his patents, his projects or more about him."

        ### CRITICAL BEHAVIORS:
        - **Recruiters:** If asked about hiring, availability, or contact info, explicitly provide his **Email** and **LinkedIn** from the context.
        - **Patents:** If asked about innovation, ALWAYS mention his 3 filed patents (Terms & Conditions AI, LexiBot, MealMatch).
        - **Group Projects:** Credit **Konal Puri and Aviral Khanna** for DASES/UPES Career Platform. Specify Mrigank's role (Mobile App/Frontend).
        - **Technical Depth:** Mention specific algorithms (e.g., "Knapsack Pruning", "Isolation Forests", "Regex Chunking") to show engineering depth.

        ### CONTEXT FROM KNOWLEDGE BASE:
        {context_text}
        """
        
        # Step 5: Generate response using Gemini
        response = client.models.generate_content(
            model=LLM_MODEL,
            contents=[
                types.Content(
                    role="user", 
                    parts=[
                        types.Part.from_text(text=system_prompt + "\n\nUser Question: " + query)
                    ]
                )
            ],
            config=types.GenerateContentConfig(
                temperature=0.7,
                max_output_tokens=1024
            )
        )
        
        return response.text

    except Exception as e:
        print(f"Error in RAG pipeline: {e}")
        return "I'm encountering a temporary issue connecting to the knowledge base. Please try again in a moment."