From 9ee82aed51dde1e7db03e1dd18d6d9bd38d0b16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=B8=D0=BD=D0=B0=D1=80=20=D0=9C=D0=B8=D1=80=D0=B7?= =?UTF-8?q?=D0=B0=D0=B3=D0=B8=D1=82=D0=BE=D0=B2?= Date: Wed, 10 Jun 2026 13:58:07 +0000 Subject: [PATCH] Initial implementation of FAQ bot with ChromaDB and MCP-style tool: update src/utils.py --- src/utils.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/utils.py b/src/utils.py index c1f0cb2..262504e 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,11 +1,14 @@ import os from pathlib import Path +import json +import httpx from langchain_ollama import OllamaEmbeddings from langchain_chroma import Chroma from langchain_text_splitters import RecursiveCharacterTextSplitter CHROMA_PATH = Path("./chroma_faq") +# Load FAQ markdown files into ChromaDB def load_faq_to_chroma(md_dir: str = "data"): Path(md_dir).mkdir(parents=True, exist_ok=True) md_files = list(Path(md_dir).glob("*.md")) @@ -22,7 +25,23 @@ def load_faq_to_chroma(md_dir: str = "data"): chroma.persist() return chroma +# Search the ChromaDB for relevant documents def search_course_docs(query: str, k: int = 3): chroma = Chroma(persist_directory=str(CHROMA_PATH), embedding_function=OllamaEmbeddings(model="nomic-embed-text")) retriever = chroma.as_retriever(search_kwargs={"k": k}) return retriever.get_relevant_documents(query) + +# MCP‑style tool: fetch metadata from a mock HTTP endpoint +# In production this would be a real MCP server. Here we use a local JSON file served by http.server. +def fetch_course_meta(query: str): + url = f"http://localhost:8000/course_meta.json" + try: + response = httpx.get(url, timeout=5.0) + response.raise_for_status() + data = response.json() + except Exception: + # Fallback to local static file if server not running + data = json.loads(Path("data/course_meta.json").read_text(encoding="utf-8")) + # Simple filtering: return items where query is in title or description + results = [item for item in data if query.lower() in item.get("title", "").lower() or query.lower() in item.get("description", "").lower()] + return results