Girish Jeswani commited on
Commit
0f18a26
·
2 Parent(s): a789c411bb818d

Merge branch 'main' of github.com:sohank-17/Neon-AI-Project

Browse files
multi_llm_chatbot_backend/app/api/routes.py CHANGED
@@ -11,6 +11,9 @@ from pydantic import BaseModel
11
  from typing import Optional, List
12
  from fastapi import UploadFile, File
13
  from app.utils.document_extractor import extract_text_from_file
 
 
 
14
  from app.utils.file_limits import is_within_upload_limit
15
 
16
  router = APIRouter()
@@ -531,6 +534,22 @@ async def debug_personas():
531
  "current_provider": current_provider
532
  }
533
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
534
  @router.get("/uploaded-files")
535
  def get_uploaded_filenames():
536
- return {"files": session_context.uploaded_files}
 
11
  from typing import Optional, List
12
  from fastapi import UploadFile, File
13
  from app.utils.document_extractor import extract_text_from_file
14
+ from app.core.orchestrator import answer_with_persona_context
15
+ from app.utils.chroma_client import add_persona_doc
16
+ import hashlib
17
  from app.utils.file_limits import is_within_upload_limit
18
 
19
  router = APIRouter()
 
534
  "current_provider": current_provider
535
  }
536
 
537
+ class PersonaQuery(BaseModel):
538
+ question: str
539
+ persona: str
540
+
541
+ @router.post("/ask/")
542
+ async def ask_question(query: PersonaQuery):
543
+ response = await answer_with_persona_context(query.question, query.persona)
544
+
545
+ # Store Q&A in vector DB
546
+ combined_text = f"Q: {query.question}\nA: {response}"
547
+ doc_id = hashlib.md5(combined_text.encode()).hexdigest() # Create a unique doc ID
548
+
549
+ add_persona_doc(combined_text, query.persona, doc_id)
550
+
551
+ return {"response": response}
552
+
553
  @router.get("/uploaded-files")
554
  def get_uploaded_filenames():
555
+ return {"files": session_context.uploaded_files}
multi_llm_chatbot_backend/app/core/orchestrator.py CHANGED
@@ -1,5 +1,8 @@
1
  from app.models.persona import Persona
2
  from typing import List
 
 
 
3
 
4
  class ChatOrchestrator:
5
  def __init__(self):
@@ -25,3 +28,16 @@ class ChatOrchestrator:
25
  context.append({"role": persona.id, "content": reply})
26
 
27
  return responses
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from app.models.persona import Persona
2
  from typing import List
3
+ from app.utils.chroma_client import query_persona_knowledge
4
+ from app.llm.gemini_client import GeminiClient
5
+ from app.llm.llm_client import LLMClient
6
 
7
  class ChatOrchestrator:
8
  def __init__(self):
 
28
  context.append({"role": persona.id, "content": reply})
29
 
30
  return responses
31
+
32
+ async def answer_with_persona_context(question: str, persona: str) -> str:
33
+ llm: LLMClient = GeminiClient()
34
+ context_chunks = query_persona_knowledge(question, persona)
35
+ context = "\n".join(context_chunks) if context_chunks else "No relevant info found."
36
+
37
+ system_prompt = f"You are a helpful assistant responding as a {persona}."
38
+ message_context = [
39
+ {"role": "system", "content": system_prompt},
40
+ {"role": "user", "content": f"Context:\n{context}\n\nQuestion:\n{question}"}
41
+ ]
42
+
43
+ return await llm.generate(system_prompt, message_context)
multi_llm_chatbot_backend/app/llm/embedding_client.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sentence_transformers import SentenceTransformer
2
+ import os
3
+
4
+ API_KEY = os.getenv("GEMINI_API_KEY")
5
+
6
+ # Using a compact, fast model good for semantic search
7
+ model = SentenceTransformer("all-MiniLM-L6-v2")
8
+
9
+ def get_embedding(text: str) -> list[float]:
10
+ embedding = model.encode(text, convert_to_numpy=True)
11
+ return embedding.tolist()
multi_llm_chatbot_backend/app/utils/chroma_client.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import chromadb
2
+ from chromadb.config import Settings
3
+ from app.llm.embedding_client import get_embedding
4
+
5
+ client = chromadb.PersistentClient(path="./chroma_storage")
6
+
7
+ collection = client.get_or_create_collection("persona_knowledge")
8
+
9
+ def add_persona_doc(text: str, persona: str, doc_id: str):
10
+ embedding = get_embedding(text)
11
+ collection.add(
12
+ documents=[text],
13
+ embeddings=[embedding],
14
+ metadatas=[{"persona": persona}],
15
+ ids=[doc_id]
16
+ )
17
+
18
+ def query_persona_knowledge(query: str, persona: str):
19
+ query_embedding = get_embedding(query)
20
+ results = collection.query(
21
+ query_embeddings=[query_embedding],
22
+ n_results=3,
23
+ where={"persona": persona}
24
+ )
25
+ return results['documents'][0] if results['documents'] else []