from __future__ import annotations import logging from typing import Any from .demo_pack import extract_photo_caption from .index import tokenize from .llm import generate_repair_checklist logger = logging.getLogger(__name__) def build_response(symptom: str, equipment_type: str, location: str, notes: str, photo_path: str | None, search_index: Any) -> tuple[str, list[list[Any]], dict[str, Any]]: query = " ".join([symptom, equipment_type, location, notes]).strip() if photo_path: photo_caption = extract_photo_caption(photo_path) query += " " + photo_caption else: photo_caption = "" section_hits = search_index.search_sections(query, top_k=5) job_hits = search_index.search_jobs(query, top_k=3) top_score = section_hits[0].score if section_hits else 0.0 too_vague = len(tokenize(symptom)) < 4 insufficient = too_vague or (not section_hits) or top_score < 0.10 citations_rows: list[list[Any]] = [] citation_lines = [] reference_texts = [] for hit in section_hits[:3]: title = hit.title citations_rows.append([f"{hit.score:.3f}", hit.kind, hit.record_id, title, hit.citation]) citation_lines.append(f"- {title} — {hit.citation} (score {hit.score:.3f})") reference_texts.append(hit.text) logger.info(f"Generating response with LLM (insufficient={insufficient})...") generated_text, stats = generate_repair_checklist( symptom=symptom, equipment_type=equipment_type, location=location, notes=notes, photo_caption=photo_caption, references=reference_texts, insufficient=insufficient ) body = generated_text + f"\n\n**Inference Stats:**\nModel: {stats['model_id']}\nAdapter: {stats['adapter']}\nTokens: {stats['total_tokens']} (P: {stats['prompt_tokens']}, C: {stats['completion_tokens']})" if citation_lines: body += "\n\nCitations:\n" + "\n".join(citation_lines) payload = { "status": "insufficient_evidence" if insufficient else "ok", "photo_caption": photo_caption, "retrieved_sections": [hit.citation for hit in section_hits], "retrieved_jobs": [hit.citation for hit in job_hits], "top_scores": [hit.score for hit in section_hits[:3]], "llm_stats": stats } return body, citations_rows, payload