From 416d77f413f1f439f18f15d94f3a1fb1ab4e2360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=80=D0=B8=D0=BB=D0=BB=20=D0=A0=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Fri, 5 Jun 2026 11:49:45 +0000 Subject: [PATCH] Add tools.py --- tools.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tools.py 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