import gradio as gr import os import sys import json import requests import random # ===================================================== # Environment variables (Hugging Face Spaces SAFE) # ===================================================== MODEL = "gpt-4.1-mini" # Updated to a valid model for Responses API API_URL = os.getenv("API_URL") if not API_URL: raise RuntimeError("API_URL not set in Hugging Face Secrets") DISABLED = os.getenv("DISABLED", "False") == "True" keys = os.getenv("OPENAI_API_KEYS") if not keys: raise RuntimeError("OPENAI_API_KEYS not set in Hugging Face Secrets") OPENAI_API_KEYS = [k.strip() for k in keys.split(",") if k.strip()] if not OPENAI_API_KEYS: raise RuntimeError("OPENAI_API_KEYS is empty") NUM_THREADS = int(os.getenv("NUM_THREADS", "2")) print("HF Space started") print("API_URL loaded") print("OPENAI_API_KEYS count:", len(OPENAI_API_KEYS)) print("NUM_THREADS:", NUM_THREADS) # ===================================================== # Exception handling # ===================================================== def exception_handler(exception_type, exception, traceback): print(f"{exception_type.__name__}: {exception}") sys.excepthook = exception_handler sys.tracebacklimit = 0 # ===================================================== # Prediction function (Responses API compatible) # ===================================================== def predict(inputs, top_p, temperature, chat_counter, chatbot, history, request: gr.Request): if not OPENAI_API_KEYS: raise RuntimeError("No OpenAI API keys available") OPENAI_API_KEY = random.choice(OPENAI_API_KEYS) headers = { "Content-Type": "application/json", "Authorization": f"Bearer {OPENAI_API_KEY}" } # Build payload for Responses API payload = { "model": MODEL, "input": inputs, "temperature": temperature, "top_p": top_p } chat_counter += 1 history.append({"role": "user", "content": inputs}) try: response = requests.post(API_URL, headers=headers, json=payload, timeout=60) print("Status code:", response.status_code) if response.status_code != 200: print("Response text:", response.text) output_text = f"Error: {response.status_code}" else: data = response.json() # Extract text output from Responses API output_text = data["output"][0]["content"][0]["text"] history.append({"role": "assistant", "content": output_text}) # Convert history to Gradio 'messages' format messages = [{"role": msg["role"], "content": msg["content"]} for msg in history] yield messages, history, chat_counter, response, gr.update(interactive=True), gr.update(interactive=True) except Exception as e: print(f"API request error: {e}") messages = [{"role": msg["role"], "content": msg["content"]} for msg in history] yield messages, history, chat_counter, None, gr.update(interactive=True), gr.update(interactive=True) # ===================================================== # UI helpers # ===================================================== def reset_textbox(): return gr.update(value="", interactive=False), gr.update(interactive=False) # ===================================================== # Gradio UI # ===================================================== title = "