A small Express + TypeScript service that answers questions using an LLM.
It automatically chooses between two paths:
- Direct mode: respond from the model only (no browsing)
- Web mode: search the web, open top pages, summarize them, then answer with source URLs
The goal is to keep answers short and beginner-friendly while returning structured JSON output.
High Level Design-->
When you send a query to the API:
- The request is validated with Zod.
- A router step decides the mode:
- Uses direct for normal / stable questions
- Switches to web if the query looks time-sensitive, numeric, price-related, trending, “latest”, etc.
- Direct mode
- Calls the chat model once
- Returns
{ answer, sources: [] }
- Web mode
- Uses Tavily Search to get results
- Opens the top pages (HTTP fetch)
- Converts HTML to text and caps content length
- Summarizes each page with the model
- Composes a final answer using only those summaries
- Returns
{ answer, sources: [url, ...] }
- Final output is validated again with Zod, and repaired once if needed.
- Node.js + TypeScript
- Express
- LangChain (RunnableSequence, RunnableBranch)
- Zod (input/output validation)
- Tavily Search API (web search)
- html-to-text (cleaning page HTML)
- CORS configured for a single allowed frontend origin
Request body
{
"q": "your question here"
}Success Response
{
"answer": "string",
"sources": ["https://example.com", "https://example2.com"]
}