Add tools.py
This commit is contained in:
@@ -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"]
|
||||||
Reference in New Issue
Block a user