| """query_classifier — uses the Groq LLM to label the query as FACTUAL / WORKFLOW / CHAT.""" |
|
|
| from src.graph.config import CLASSIFIER_TEMPLATE |
| from src.graph.utils import traced |
| from src.llm_handler import classify |
|
|
| LABEL_MAP = { |
| "FACTUAL": "factual_lookup", |
| "WORKFLOW": "workflow_guidance", |
| "CHAT": "general_chat", |
| } |
|
|
|
|
| def _parse_label(raw: str) -> str: |
| """Pull the first known label out of the raw LLM output.""" |
| if not raw: |
| return "factual_lookup" |
| upper = raw.upper() |
| for label, qtype in LABEL_MAP.items(): |
| if label in upper: |
| return qtype |
| return "factual_lookup" |
|
|
|
|
| @traced("classifier") |
| def classify_query(state: dict) -> dict: |
| query = state.get("query", "").strip() |
| summary = state.get("memory_summary", "") |
| if not query: |
| return { |
| "query_type": "general_chat", |
| "classifier_raw": "", |
| "_summary": "empty query → chat", |
| "_payload": {"raw": ""}, |
| } |
|
|
| prompt = CLASSIFIER_TEMPLATE.format(query=query, summary=summary or "(none)") |
| raw = classify(prompt) |
| qtype = _parse_label(raw) |
| return { |
| "query_type": qtype, |
| "classifier_raw": raw, |
| "_summary": qtype, |
| "_payload": {"raw": raw, "prompt_preview": prompt[:200]}, |
| } |
|
|