# app.py import os import time import traceback import openai import gradio as gr # ---- Config / Defaults ---- MODEL_NAME = "gpt-3.5-turbo" # change to "gpt-4" if you have access DEFAULT_SYSTEM_PROMPT = ( "You are a kind, empathetic bilingual assistant (Urdu & English). " "Answer concisely and helpfully. If user writes in Urdu, reply in Urdu; " "if in English, reply in English. Preserve politeness and clarity." ) # Load API key from env (Hugging Face secret should set OPENAI_API_KEY) openai.api_key = os.getenv("OPENAI_API_KEY") # ---- Helpers ---- def detect_language(text: str) -> str: # Very simple heuristic: presence of Arabic/Persian/Urdu characters for ch in text: if '\u0600' <= ch <= '\u06FF': return "ur" return "en" def fallback_reply(user_message: str): """If no API key or API fails, return a helpful local reply.""" lang = detect_language(user_message) if lang == "ur": # Some friendly fallback phrases in Urdu responses = [ "معذرت — ابھی سرور سے رابطہ ممکن نہیں۔ میں آپ کا پیغام نوٹ کر رہا ہوں: " + user_message, "میں فی الحال API سے جڑ نہیں پارہا، مگر بتائیں میں ابھی بھی سن رہا ہوں۔", "آپ نے کہا: " + user_message + " — جب سروس واپس آئے گی تو مفصل جواب دوں گا۔" ] else: responses = [ "Sorry — I'm temporarily offline. Noting your message: " + user_message, "I can't reach the API right now, but I'm listening. Please try again shortly.", "You said: " + user_message + " — I'll respond fully once service is available." ] # rotate based on time to vary replies return responses[int(time.time()) % len(responses)] def call_openai_chat(system_prompt, user_message, max_tokens=512, temperature=0.7, top_p=0.95): """ Call OpenAI ChatCompletion and return assistant text. Raises Exception on failure. """ # messages: system + user messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": user_message}] resp = openai.ChatCompletion.create( model=MODEL_NAME, messages=messages, max_tokens=max_tokens, temperature=temperature, top_p=top_p, ) # defensive extraction try: text = resp.choices[0].message.content except Exception: text = resp.choices[0].text if hasattr(resp.choices[0], "text") else "" return text.strip() # ---- Main chat handler ---- def respond(message, chat_history, system_message, max_tokens, temperature, top_p): """ message: user input string chat_history: list of tuples [(user, bot), ...] system_message: custom system prompt (string) max_tokens, temperature, top_p: numeric controls """ if chat_history is None: chat_history = [] system_prompt = system_message.strip() or DEFAULT_SYSTEM_PROMPT # if empty message if not message or not message.strip(): return chat_history + [("","Please type something or ask a question.")] # try OpenAI if key present if openai.api_key: try: reply = call_openai_chat(system_prompt, message, max_tokens=int(max_tokens), temperature=float(temperature), top_p=float(top_p)) except Exception as e: # log traceback to help debugging (visible in Space logs) print("OpenAI call failed:", str(e)) traceback.print_exc() reply = ( "معذرت! سروس سے رابطے میں مسئلہ آیا۔ براہِ کرم بعد میں دوبارہ کوشش کریں۔" if detect_language(message) == "ur" else "Sorry! There was an issue contacting the service. Please try again later." ) else: # No API key — graceful fallback reply = fallback_reply(message) chat_history = chat_history + [(message, reply)] return chat_history # ---- Gradio UI ---- with gr.Blocks(theme=gr.themes.Default()) as demo: gr.Markdown("