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