import os import logging from pathlib import Path logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) _model = None def get_llm(): global _model if _model is not None: return _model try: from llama_cpp import Llama except ImportError: raise RuntimeError("llama-cpp-python is required for model inference. Please install it.") import os fallback_paths = [ Path("/data/MiniCPM5-1B-Q4_K_M.gguf"), Path(__file__).resolve().parent.parent / "models" / "MiniCPM5-1B-Q4_K_M.gguf" ] model_path = fallback_paths[1] for p in fallback_paths: if p.exists(): model_path = p break if not model_path.exists(): raise RuntimeError(f"Model not found at {model_path}. Model inference requires a valid model.") logger.info(f"Loading model from {model_path}") _model = Llama(model_path=str(model_path), n_ctx=2048, n_threads=4, verbose=False) return _model def generate_repair_checklist(symptom: str, equipment_type: str, location: str, notes: str, photo_caption: str, references: list[str], insufficient: bool) -> tuple[str, dict]: llm = get_llm() refs_text = "\n\n".join([f"Reference {i+1}:\n{ref}" for i, ref in enumerate(references)]) if references else "None available." if insufficient: prompt = f"""You are an expert field repair assistant. The user provided insufficient information to make a confident diagnosis. Equipment: {equipment_type} Location: {location} Symptom: {symptom} Notes: {notes} Photo Context: {photo_caption} Explain that there is insufficient evidence and suggest next steps to diagnose the issue (e.g. check meter, fault code, inspect obvious hazards). Start with a safety reminder. Response:""" else: prompt = f"""You are an expert field repair assistant. Based on the symptom, equipment type, location, notes, and the provided manual references, create a short, actionable checklist for diagnosing and fixing the issue. Always start with a safety reminder. Do NOT use hallucinated information. Rely strictly on the references provided. Equipment: {equipment_type} Location: {location} Symptom: {symptom} Notes: {notes} Photo Context: {photo_caption} References: {refs_text} Provide the response as a bulleted checklist starting with "Safety reminder: " Checklist:""" response = llm( prompt, max_tokens=300, temperature=0.3, stop=["\n\n\n"] ) text = response['choices'][0]['text'].strip() stats = { "model_id": "nvidia/NeMoTRON-3-Nano-4B-Instruct", "adapter": "llama_cpp", "prompt_tokens": response['usage']['prompt_tokens'], "completion_tokens": response['usage']['completion_tokens'], "total_tokens": response['usage']['total_tokens'] } logger.info(f"Inference complete. Stats: {stats}") return text, stats