import gradio as gr from openai import OpenAI def respond(message, chat_history, api_key): # Failsafe to ensure history initializes as an empty list if chat_history is None: chat_history = [] # Gatekeeper: Halt execution if no compute resource is provided if not api_key: chat_history.append({"role": "user", "content": message}) chat_history.append({"role": "assistant", "content": "System locked: Please enter your OpenAI API Key in the secure box above."}) return "", chat_history try: client = OpenAI(api_key=api_key) # System prompt openai_messages = [ { "role": "system", "content": "You are an elite Florida State University (FSU) intelligence agent. You provide highly accurate, actionable information regarding FSU campus life, academic infrastructure, and Seminoles Division 1 football history. Default to thinking in systems. Be concise, eliminate filler, and output structured data where appropriate." } ] # Pass the direct Gradio history into the OpenAI pipeline openai_messages.extend(chat_history) openai_messages.append({"role": "user", "content": message}) # Execute query response = client.chat.completions.create( model="gpt-4o-mini", messages=openai_messages, temperature=0.4 ) bot_reply = response.choices[0].message.content # Append the new interaction using the native dictionary format chat_history.append({"role": "user", "content": message}) chat_history.append({"role": "assistant", "content": bot_reply}) return "", chat_history except Exception as e: chat_history.append({"role": "user", "content": message}) chat_history.append({"role": "assistant", "content": f"Pipeline Error: {str(e)}"}) return "", chat_history # Custom CSS for the glassmorphic visual interface glassmorphism_css = """ body { background: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%); } .gradio-container { background: rgba(255, 255, 255, 0.65) !important; backdrop-filter: blur(16px) !important; -webkit-backdrop-filter: blur(16px) !important; border-radius: 18px !important; border: 1px solid rgba(255, 255, 255, 0.5) !important; box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.07) !important; } """ with gr.Blocks() as demo: gr.Markdown("## 🍢 FSU Intelligence Node") gr.Markdown("A domain-specific AI pipeline engineered for Florida State University logistics and Division 1 football strategy.\n\n*Compute requires user-provided API authentication.*") # 1. API Key Input - Isolated from the chat submission wipe with gr.Row(): api_input = gr.Textbox( label="OpenAI API Key (Required)", placeholder="sk-proj-...", type="password", info="Injected dynamically at runtime. Keys are not stored or logged." ) # 2. Main Chat Display - Removed the 'type' parameter as it is now strictly implicit chatbot = gr.Chatbot(height=450, label="Intelligence Feed") # 3. User Input Area with gr.Row(): msg = gr.Textbox( label="Query Input", placeholder="Type your query here and press Enter...", scale=4 ) submit_btn = gr.Button("Send", variant="primary", scale=1) # 4. Quick-Load Examples gr.Examples( examples=[ "Break down the structural timeline of FSU's Division 1 football championships.", "What are the core technology infrastructure facilities on the Tallahassee campus?", "Provide a statistical overview of the 2013 Seminoles season." ], inputs=msg ) # 5. Explicit Event Binding msg.submit(respond, inputs=[msg, chatbot, api_input], outputs=[msg, chatbot]) submit_btn.click(respond, inputs=[msg, chatbot, api_input], outputs=[msg, chatbot]) if __name__ == "__main__": demo.launch( css=glassmorphism_css, theme=gr.themes.Default(primary_hue="red", neutral_hue="zinc") )