diff --git a/tools.py b/tools.py new file mode 100644 index 0000000..d2fe16a --- /dev/null +++ b/tools.py @@ -0,0 +1,56 @@ +"""Tool definitions for the FAQ bot. + +The module defines two tools: +1. `search_course_docs` – a semantic search over the local Chroma FAQ store. +2. `fetch_course_meta` – a simple HTTP GET to a local JSON file that mimics an MCP + metadata service. + +Both tools are decorated with `@tool` so that LangChain can expose them to the +agent. +""" + +import json +import os +from pathlib import Path +from typing import Any + +import httpx +from langchain.tools import tool + +from config import COURSE_META_JSON +from vector_store import search_course_docs + +# --------------------------------------------------------------------------- +# 1. Semantic search tool +# --------------------------------------------------------------------------- +@tool("search_course_docs", "Search local FAQ documents.") +async def search_course_docs_tool(query: str, k: int = 3) -> str: + """Return top‑k relevant FAQ snippets for *query*. + + The function is asynchronous to match the signature expected by LangChain + agents. It simply forwards the call to the synchronous helper in + ``vector_store``. + """ + return search_course_docs(query, k) + +# --------------------------------------------------------------------------- +# 2. Metadata fetch tool – MCP‑style +# --------------------------------------------------------------------------- +@tool("fetch_course_meta", "Get course metadata from a local JSON file.") +async def fetch_course_meta_tool(query: str) -> str: + """Return JSON string of metadata matching *query*. + + The function reads a static JSON file. In a real deployment this would be a + HTTP request to an MCP server. For the purposes of the assignment we keep + it simple and local. + """ + if not Path(COURSE_META_JSON).exists(): + return f"Metadata file {COURSE_META_JSON} not found." + data = json.loads(Path(COURSE_META_JSON).read_text(encoding="utf-8")) + # Very naive lookup: return the whole file if query is empty or substring + if not query or query.lower() in json.dumps(data).lower(): + return json.dumps(data, indent=2) + return f"No metadata found for query: {query}." + +# Expose the tools for external imports +__all__ = ["search_course_docs_tool", "fetch_course_meta_tool"] \ No newline at end of file