| import chromadb |
| from sklearn.cluster import KMeans |
| import pandas as pd |
| import json |
| import ast |
| from itertools import groupby |
| import uuid |
| from datetime import datetime |
| from pathlib import Path |
|
|
| root_dir = Path(__file__).parent.parent |
| data_dir = root_dir / "datasets" |
|
|
| embed_faq_df = pd.read_csv(data_dir / "processed" / "bank_faq" / "embed_faq.csv") |
|
|
| |
| client = chromadb.PersistentClient(path="./chroma_db") |
|
|
| |
| |
|
|
| |
| collection = client.get_or_create_collection( |
| name="bank_faq", |
| metadata={"hnsw:space": "cosine"} |
| ) |
|
|
| embed_faq_df["embedding"] = embed_faq_df["embedding"].apply(ast.literal_eval) |
| |
| |
| ids = [ |
| f"doc_{row['source_id']}_chunk_{row['chunk_num']}" |
| for _, row in embed_faq_df.iterrows() |
| ] |
| embeddings = embed_faq_df["embedding"].tolist() |
| documents = embed_faq_df["text"].tolist() |
| metadatas = [ |
| { |
| "doc_id": f"doc_{row['source_id']}_chunk_{row['chunk_num']}", |
| "domain": row["domain"], |
| "source_id": row["source_id"], |
| "chunk_num": row["chunk_num"], |
| "question": row["question"] |
| } |
| for _, row in embed_faq_df.iterrows() |
| ] |
|
|
| |
| |
| |
| |
|
|
| |
| collection.add( |
| ids=ids, |
| embeddings=embeddings, |
| documents=documents, |
| metadatas=metadatas |
| ) |
|
|
| print(f"Stored {collection.count()} documents") |
|
|
| faq_collection = client.get_collection(name="bank_faq") |
| results = faq_collection.get( |
| include=["documents", "metadatas"] |
| ) |
|
|
| source_id_to_doc_ids = {} |
| for doc_id, meta in zip(ids, metadatas): |
| source_id = meta["source_id"] |
| if source_id not in source_id_to_doc_ids: |
| source_id_to_doc_ids[source_id] = [] |
| source_id_to_doc_ids[source_id].append(doc_id) |
|
|
| |
| groups = {} |
| for doc_id, meta, text in zip(results["ids"], results["metadatas"], results["documents"]): |
| source_id = meta["source_id"] |
| if source_id not in groups: |
| groups[source_id] = [] |
| groups[source_id].append({ |
| "doc_id": doc_id, |
| "chunk_num": int(meta["chunk_num"]), |
| "domain": meta["domain"], |
| "question": meta["question"], |
| "text": text.split("A:", 1)[1].strip() if "A:" in text else text, |
| }) |
|
|
| |
| viewable = [] |
| for source_id, chunks in groups.items(): |
| chunks = sorted(chunks, key=lambda x: x["chunk_num"]) |
| |
| entry = { |
| "id": source_id, |
| "domain": chunks[0]["domain"], |
| "question": chunks[0]["question"], |
| } |
|
|
| if len(chunks) == 1: |
| entry["answer"] = chunks[0]["text"] |
| else: |
| entry["answer"] = {"chunks": [{"chunk": c["chunk_num"] + 1, "doc_id": c["doc_id"], "text": c["text"]} for c in chunks]} |
|
|
| viewable.append(entry) |
|
|
|
|
| with open("chroma_preview.json", "w") as f: |
| json.dump(viewable, f, indent=2) |
|
|
| print("Saved to chroma_preview.json") |
|
|
| with open("chroma_preview.json", "r") as f: |
| faq_db = json.load(f) |
|
|
| for item in faq_db: |
| source_id = item["id"] |
| item["relevant_doc_ids"] = source_id_to_doc_ids.get(source_id, []) |
|
|
| with open("chroma_preview.json", "w") as f: |
| json.dump(faq_db, f, indent=2) |
|
|
| |
| chat_collection = client.get_or_create_collection(name="chat_history") |
|
|
| def create_new_chat(): |
| |
| chat_id = str(uuid.uuid4()) |
| print(f"New chat created: {chat_id}") |
| return chat_id |
|
|
| def get_chat_history(chat_id): |
| """Retrieve full history of a specific chat.""" |
| results = chat_collection.get( |
| where={"chat_id": chat_id} |
| ) |
|
|
| |
| history = [] |
| for doc, meta in zip(results["documents"], results["metadatas"]): |
| history.append({ |
| "query": doc, |
| "answer": meta["answer"], |
| "timestamp": meta["timestamp"] |
| }) |
|
|
| |
| history.sort(key=lambda x: x["timestamp"]) |
| return history |
|
|
| def load_chats_from_db(): |
| |
| try: |
| results = chat_collection.get(include=["metadatas", "documents"]) |
| except Exception: |
| return {} |
|
|
| chats = {} |
| for doc, meta in zip(results["documents"], results["metadatas"]): |
| chat_id = meta.get("chat_id") |
| chat_name = meta.get("chat_name", "Chat 1") |
| timestamp = meta.get("timestamp", "") |
| query = doc |
| answer = meta.get("answer", "") |
|
|
| if chat_name not in chats: |
| chats[chat_name] = {"messages": [], "chat_id": chat_id} |
|
|
| chats[chat_name]["messages"].append({"role": "user", "content": query, "timestamp": timestamp}) |
| chats[chat_name]["messages"].append({"role": "assistant", "content": answer, "timestamp": timestamp}) |
|
|
| |
| for chat_name in chats: |
| chats[chat_name]["messages"].sort(key=lambda x: x.get("timestamp", "")) |
|
|
| return chats |
|
|
| def delete_chat(chat_id: str): |
| """Remove a chat from ChromaDB and the JSON log.""" |
| |
| results = chat_collection.get(where={"chat_id": chat_id}) |
| if results["ids"]: |
| chat_collection.delete(ids=results["ids"]) |
|
|
| print(f"Chat deleted: {chat_id}") |
|
|
|
|