import torchimport jsonimport refrom transformers import AutoTokenizer, AutoModelForCausalLM # --- 1. MODEL SETUP ---model_name = "dheeyantra/dhee-nxtgen-qwen3-indic"tokenizer = AutoTokenizer.from_pretrained(model_name)model = AutoModelForCausalLM.from_pretrained( model_name, trust_remote_code=True, device_map="auto", torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32) # --- 2. TOOLS & SYSTEM PROMPT ---tools = [{ "name": "book_appointment", "description": "Book an appointment for the user.", "parameters": { "type": "object", "properties": { "date": {"type": "string", "description": "Date in YYYY-MM-DD format"}, "time": {"type": "string", "description": "Time in HH:MM (24h) format"}, "purpose": {"type": "string", "description": "The medical reason or department"} }, "required": ["date", "time", "purpose"] }}] # We provide the current date so the model can resolve "tomorrow" or "next Monday"SYSTEM_PROMPT = f"""You are a helpful AI assistant.Today's Date: 2026-01-08 (Thursday). Available Tools:{json.dumps(tools, indent=2)} Rules:1. If details (date, time, purpose) are missing, ask the user in Hindi.2. If all details are present, output ONLY a <tool_call> JSON.3. After a tool result is provided, confirm the booking to the user in Hindi.""" # --- 3. BACKEND FUNCTION ---def execute_booking(date, time, purpose): # Simulated backend logic if "10:00" in time: # Simulate a busy slot return {"status": "error", "message": "यह समय पहले से बुक है। कृपया कोई और समय चुनें।"} return {"status": "success", "id": "APP-9921", "doctor": "Dr. Verma"} # --- 4. THE INTERACTION ENGINE ---def run_conversation(user_input, history): # Add user input to history history.append({"role": "user", "content": user_input}) # Construct ChatML prompt prompt = f"<|im_start|>system\n{SYSTEM_PROMPT}<|im_end|>\n" for msg in history: prompt += f"<|im_start|>{msg['role']}\n{msg['content']}<|im_end|>\n" prompt += "<|im_start|>assistant\n" # Generate inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate(**inputs, max_new_tokens=256, temperature=0.1) response = tokenizer.decode(outputs[0], skip_special_tokens=True).split("assistant")[-1].strip() # Check if the model wants to call a tool tool_match = re.search(r"<tool_call>(.*?)</tool_call>", response, re.DOTALL) if tool_match: print(f"\n[MODEL REQUESTED TOOL]: {response}") call_data = json.loads(tool_match.group(1).strip()) # Execute the function result = execute_booking(**call_data['arguments']) print(f"[TOOL RESULT]: {result}") # Feed result back to model for final response history.append({"role": "assistant", "content": response}) history.append({"role": "system", "content": f"Tool Result: {json.dumps(result)}"}) # Final confirmation generation return run_conversation("Please confirm the result to the user.", history) return response # --- 5. TEST SCENARIO ---chat_history = [] print("--- Chatbot Started (Today is 2026-01-08) ---") # Step 1: User provides partial infoquery_1 = "मेरे लिए डेंटिस्ट का अपॉइंटमेंट बुक करें।"print(f"\nUser: {query_1}")res_1 = run_conversation(query_1, chat_history)chat_history.append({"role": "assistant", "content": res_1})print(f"Assistant: {res_1}") # Step 2: User provides the restquery_2 = "कल दोपहर 2 बजे।"print(f"\nUser: {query_2}")res_2 = run_conversation(query_2, chat_history)print(f"Assistant: {res_2}")