chandanasunkara commited on
Commit
c6ce494
·
1 Parent(s): b4a89ba

BACKEND : Setup Database to store and retrieve information

Browse files
multi_llm_chatbot_backend/app/api/routes.py CHANGED
@@ -10,6 +10,9 @@ from pydantic import BaseModel
10
  from typing import Optional, List
11
  from fastapi import UploadFile, File
12
  from app.utils.document_extractor import extract_text_from_file
 
 
 
13
 
14
  router = APIRouter()
15
 
@@ -534,4 +537,20 @@ async def debug_personas():
534
  },
535
  "context_length": len(session_context.full_log),
536
  "current_provider": current_provider
537
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  from typing import Optional, List
11
  from fastapi import UploadFile, File
12
  from app.utils.document_extractor import extract_text_from_file
13
+ from app.core.orchestrator import answer_with_persona_context
14
+ from app.utils.chroma_client import add_persona_doc
15
+ import hashlib
16
 
17
  router = APIRouter()
18
 
 
537
  },
538
  "context_length": len(session_context.full_log),
539
  "current_provider": current_provider
540
+ }
541
+
542
+ class PersonaQuery(BaseModel):
543
+ question: str
544
+ persona: str
545
+
546
+ @router.post("/ask/")
547
+ async def ask_question(query: PersonaQuery):
548
+ response = await answer_with_persona_context(query.question, query.persona)
549
+
550
+ # Store Q&A in vector DB
551
+ combined_text = f"Q: {query.question}\nA: {response}"
552
+ doc_id = hashlib.md5(combined_text.encode()).hexdigest() # Create a unique doc ID
553
+
554
+ add_persona_doc(combined_text, query.persona, doc_id)
555
+
556
+ return {"response": response}
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,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sentence_transformers import SentenceTransformer
2
+ import os
3
+ import httpx
4
+ import hashlib
5
+
6
+ API_KEY = os.getenv("GEMINI_API_KEY")
7
+
8
+ # Using a compact, fast model good for semantic search
9
+ model = SentenceTransformer("all-MiniLM-L6-v2")
10
+
11
+ def get_embedding(text: str) -> list[float]:
12
+ # Use deterministic hash → convert to float vector
13
+ hashed = hashlib.sha256(text.encode()).hexdigest()
14
+ return [int(hashed[i:i+4], 16) / 65536.0 for i in range(0, len(hashed), 4)]
multi_llm_chatbot_backend/app/main.py CHANGED
@@ -1,7 +1,7 @@
1
  # app/main.py
2
  from fastapi import FastAPI
3
  from fastapi.middleware.cors import CORSMiddleware
4
- from app.api.routes import router
5
  from dotenv import load_dotenv
6
  import os
7
 
@@ -23,7 +23,8 @@ app.add_middleware(
23
  )
24
 
25
  # Include route definitions
26
- app.include_router(router)
 
27
 
28
  @app.get("/")
29
  def root():
 
1
  # app/main.py
2
  from fastapi import FastAPI
3
  from fastapi.middleware.cors import CORSMiddleware
4
+ from app.api.routes import router as api_router
5
  from dotenv import load_dotenv
6
  import os
7
 
 
23
  )
24
 
25
  # Include route definitions
26
+ # app.include_router(router)
27
+ app.include_router(api_router, prefix="/api")
28
 
29
  @app.get("/")
30
  def root():
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 []