Spaces:
Running
Running
| 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") | |
| ) |