|
|
from flask import Flask, render_template, request, jsonify |
|
|
from flask_cors import CORS |
|
|
from dotenv import load_dotenv |
|
|
import os |
|
|
from langchain_pinecone import PineconeVectorStore |
|
|
from langchain.chains import create_retrieval_chain |
|
|
from langchain.chains.combine_documents import create_stuff_documents_chain |
|
|
from langchain_core.prompts import ChatPromptTemplate |
|
|
from langchain_community.chat_models import ChatOllama |
|
|
from langchain_huggingface import HuggingFaceEmbeddings |
|
|
|
|
|
|
|
|
def download_hugging_face_embeddings(): |
|
|
embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2') |
|
|
return embeddings |
|
|
|
|
|
|
|
|
system_prompt = ( |
|
|
"You are an intelligent Personal Portfolio Assistant that answers questions about the user's background, work, and projects. " |
|
|
"Use the retrieved context below to provide accurate and natural responses. " |
|
|
"If the context does not contain the answer, respond with 'I'm not sure about that.' " |
|
|
"Keep your answer concise." |
|
|
"\n\n" |
|
|
"Context:\n{context}" |
|
|
) |
|
|
|
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
pinecone_api_key = os.environ.get("PINECONE_API_KEY") |
|
|
if not pinecone_api_key: |
|
|
raise ValueError("Missing PINECONE_API_KEY in environment variables.") |
|
|
|
|
|
app = Flask(__name__) |
|
|
CORS(app) |
|
|
|
|
|
|
|
|
embeddings = download_hugging_face_embeddings() |
|
|
index_name = "portfolio" |
|
|
|
|
|
docsearch = PineconeVectorStore.from_existing_index(index_name=index_name, embedding=embeddings) |
|
|
retriever = docsearch.as_retriever(search_type="similarity", search_kwargs={"k": 3}) |
|
|
|
|
|
|
|
|
chatModel = ChatOllama(model="gemma3:1b", temperature=0.1, max_tokens=512) |
|
|
|
|
|
|
|
|
prompt = ChatPromptTemplate.from_messages( |
|
|
[ |
|
|
("system", system_prompt), |
|
|
("human", "{input}"), |
|
|
] |
|
|
) |
|
|
|
|
|
question_answer_chain = create_stuff_documents_chain(chatModel, prompt) |
|
|
rag_chain = create_retrieval_chain(retriever, question_answer_chain) |
|
|
|
|
|
|
|
|
@app.route("/") |
|
|
def index(): |
|
|
return "✅ RAG server running" |
|
|
|
|
|
|
|
|
@app.route("/get", methods=["POST"]) |
|
|
def chat(): |
|
|
user_msg = request.form.get("msg") or request.json.get("msg") |
|
|
|
|
|
if not user_msg: |
|
|
return jsonify({"error": "No message sent"}), 400 |
|
|
|
|
|
try: |
|
|
response = rag_chain.invoke({"input": user_msg}) |
|
|
answer = response.get("answer", "Sorry, I couldn’t find an answer.") |
|
|
return jsonify({"reply": answer}) |
|
|
except Exception as e: |
|
|
print("Error:", e) |
|
|
return jsonify({"reply": f"Server Error: {str(e)}"}) |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
port = int(os.environ.get('PORT', 2025)) |
|
|
app.run(host="0.0.0.0", port=port, debug=False) |
|
|
|