Spaces:
Runtime error
Runtime error
File size: 10,824 Bytes
5305e57 599d7c0 a47572b 9109896 a47572b 9109896 a47572b 9109896 5305e57 9109896 5305e57 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 599d7c0 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 599d7c0 9109896 49cbbe1 a4b58ab bc279d8 9109896 bc279d8 9109896 8cd9a28 dde5e28 bc279d8 dde5e28 9109896 599d7c0 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 9109896 a47572b 599d7c0 9109896 599d7c0 9109896 599d7c0 a47572b 599d7c0 9109896 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
import os
from openai import OpenAI
from datetime import datetime
import gradio as gr
import time
import openai # Already imported OpenAI above, this line is redundant
# --- Constants ---
# Use a model available in the dropdown as the default
DEFAULT_MODEL = "gpt-4o-mini-2024-07-18"
DEFAULT_TEMPERATURE = 1.0
DEFAULT_TOP_P = 1.0
DEFAULT_FREQ_PENALTY = 0
DEFAULT_PRES_PENALTY = 0
MAX_TOKENS = 2048 # This is often controlled by the model, but can be a limit
MAX_HISTORY_LENGTH = 5
# --- API Key and Client Initialization ---
# Ensure the API key is set in your Hugging Face Space secrets
API_KEY = os.getenv("OPENAI_API_KEY")
if not API_KEY:
# Provide a clear error message if the key is missing
# In a real HF Space, you might raise an exception or disable the UI
print("Error: OPENAI_API_KEY environment variable not set.")
# Consider adding a gr.Markdown warning in the UI as well if API_KEY is None
# For now, we'll let it proceed, but OpenAI() will likely raise an error later.
client = OpenAI(api_key=API_KEY)
# --- Helper Functions ---
def get_openai_response(prompt, model=DEFAULT_MODEL, temperature=DEFAULT_TEMPERATURE, top_p=DEFAULT_TOP_P,
frequency_penalty=DEFAULT_FREQ_PENALTY, presence_penalty=DEFAULT_PRES_PENALTY,
max_tokens=MAX_TOKENS, system_prompt="", chat_history=None):
"""Gets a response from the OpenAI API, handling errors and streaming."""
today_day = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
messages = []
# Add system prompt if provided
effective_system_prompt = f"Today's date is: {today_day}. {system_prompt}".strip()
if effective_system_prompt:
messages.append({"role": "system", "content": effective_system_prompt})
# Add chat history
if chat_history:
for turn in chat_history:
# Ensure turn has two elements before trying to access them
if len(turn) == 2 and turn[0] is not None and turn[1] is not None:
messages.append({"role": "user", "content": str(turn[0])}) # Ensure content is string
messages.append({"role": "assistant", "content": str(turn[1])}) # Ensure content is string
# else: # Optional: Handle malformed history entries
# print(f"Skipping malformed history entry: {turn}")
# Add the current user prompt
messages.append({"role": "user", "content": prompt})
try:
# *** This is the correct, modern API call for chat models ***
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=temperature,
max_tokens=max_tokens, # Correct parameter name for this call
top_p=top_p,
frequency_penalty=frequency_penalty,
presence_penalty=presence_penalty,
# response_format={"type": "text"}, # Usually not needed unless forcing JSON etc. Let model decide default.
stream=True # Enable streaming
)
collected_messages = []
full_reply_content = "" # Initialize before loop
for chunk in response:
# Check if delta and content exist before accessing
if chunk.choices and chunk.choices[0].delta and chunk.choices[0].delta.content is not None:
chunk_message = chunk.choices[0].delta.content
collected_messages.append(chunk_message)
full_reply_content = ''.join(collected_messages)
yield full_reply_content # Yield the accumulated message
# Use specific exceptions from the openai library
except openai.APIConnectionError as e:
print(f"OpenAI API request failed: {e}")
yield f"Error: Could not connect to OpenAI API. {e}"
except openai.RateLimitError as e:
print(f"OpenAI API request failed: {e}")
yield f"Error: Rate limit exceeded. Please try again later. {e}"
except openai.AuthenticationError as e:
print(f"OpenAI API request failed: {e}")
yield f"Error: Authentication failed. Check your API key. {e}"
except openai.APIStatusError as e:
print(f"OpenAI API request failed: {e}")
yield f"Error: OpenAI API returned an error (Status: {e.status_code}). {e}"
except Exception as e:
print(f"An unexpected error occurred: {e}")
yield f"An unexpected error occurred: {e}"
def update_ui(message, chat_history, model, temperature, top_p, frequency_penalty, presence_penalty, system_prompt, history_length):
"""Updates the Gradio UI; handles streaming response."""
if not message: # Don't send empty messages
yield "", chat_history
return
# Trim history before sending to API if it's longer than needed for context
# (Optional optimization, the API call does include full history passed here)
# history_for_api = chat_history[-(MAX_HISTORY_LENGTH*2):] # Keep pairs
bot_message_gen = get_openai_response(
prompt=message, model=model, temperature=temperature, top_p=top_p,
frequency_penalty=frequency_penalty, presence_penalty=presence_penalty,
system_prompt=system_prompt, chat_history=chat_history # Pass full history for context
)
chat_history.append((message, "")) # Add user message and placeholder for bot response
# Stream the response
for bot_message_chunk in bot_message_gen:
chat_history[-1] = (message, bot_message_chunk) # Update the last entry with the streamed chunk
# Control visibility based on the slider
visible_history = chat_history[-int(history_length):] if history_length > 0 else []
# time.sleep(0.02) # Slightly shorter delay might feel more responsive
yield "", visible_history
# --- Gradio Interface ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
# Keep your informative Markdown sections
gr.Markdown("# Chat with OpenAI Models") # Updated Title
gr.Markdown("β GPT-4.5 experiment details from Feb 27, 2025...") # Keep context
gr.Markdown("β [Buy me a Coffee](https://buymeacoffee.com/diegocp01m)")
gr.Markdown("---")
gr.Markdown("""
π **GPT-4.5 EXPERIMENT RECAP:** GPT-4.5 was briefly accessible via API on Feb 27, 2025.
This space allowed free access during that window.
π **Chat Completions Metrics (Feb 27, 2025):**
- 111 requests
- 64,764 Total tokens processed
- Total spend: $10.99
This space went live at 4:23 PM ET, Feb 27, 2025 until 8:53 PM ET. [Read More](https://x.com/diegocabezas01/status/1895291365376041045)
Results from OpenAI platform: π
""")
gr.Image("https://pbs.twimg.com/media/Gk1tVnRXkAASa2U?format=jpg&name=4096x4096", elem_id="gpt4_5_image")
gr.Markdown("Chat with available models like GPT-4o mini below: π")
with gr.Row():
with gr.Column(scale=4):
chatbot = gr.Chatbot(
label="Chat Window", # Added label for clarity
show_label=False,
avatar_images=(
# Using generic user icon
"https://cdn-icons-png.flaticon.com/512/1077/1077114.png", # User
# Using generic AI icon
"https://cdn-icons-png.flaticon.com/512/8649/8649540.png" # AI
),
render_markdown=True,
height=500,
bubble_full_width=False # Optional: makes bubbles look nicer
)
msg = gr.Textbox(
label="Your Message", # Added label
placeholder="Type your message here and press Enter...",
scale=4,
show_label=False,
container=False # Makes it sit closer to the button
)
with gr.Accordion("Advanced Options", open=False):
model_select = gr.Dropdown(
label="Model",
# Ensure these models are available to your API key
choices=["gpt-4o-mini-2024-07-18", "gpt-3.5-turbo-0125", "gpt-4o"],
value=DEFAULT_MODEL, # Use the constant defined above
interactive=True
)
temperature_slider = gr.Slider(label="Temperature (Randomness)", minimum=0.0, maximum=2.0, value=DEFAULT_TEMPERATURE, step=0.1, interactive=True)
top_p_slider = gr.Slider(label="Top P (Nucleus Sampling)", minimum=0.0, maximum=1.0, value=DEFAULT_TOP_P, step=0.05, interactive=True)
frequency_penalty_slider = gr.Slider(label="Frequency Penalty (Discourage repetition)", minimum=-2.0, maximum=2.0, value=DEFAULT_FREQ_PENALTY, step=0.1, interactive=True)
presence_penalty_slider = gr.Slider(label="Presence Penalty (Discourage repeating topics)", minimum=-2.0, maximum=2.0, value=DEFAULT_PRES_PENALTY, step=0.1, interactive=True)
system_prompt_textbox = gr.Textbox(label="System Prompt", placeholder="e.g., You are a helpful assistant.", lines=3, interactive=True)
history_length_slider = gr.Slider(label="Chat History Display Length", minimum=1, maximum=20, value=MAX_HISTORY_LENGTH, step=1, interactive=True)
with gr.Row():
# Place clear button first maybe?
clear = gr.Button("Clear Chat")
send = gr.Button("Send Message", variant="primary") # Make send more prominent
# --- Event Handlers ---
# Define reusable inputs list
inputs = [
msg, chatbot, model_select, temperature_slider, top_p_slider,
frequency_penalty_slider, presence_penalty_slider, system_prompt_textbox,
history_length_slider
]
# Define reusable outputs list
outputs = [msg, chatbot]
# Connect send button click
send.click(
update_ui,
inputs=inputs,
outputs=outputs,
queue=True # Use queue for handling multiple users potentially
)
# Connect textbox submit (Enter key)
msg.submit(
update_ui,
inputs=inputs,
outputs=outputs,
queue=True
)
# Connect clear button
# Clears the message box and the chatbot history
clear.click(lambda: (None, []), None, outputs=[msg, chatbot], queue=False)
gr.Examples(
examples=["Tell me about the latest AI developments", "Write a short story about a friendly robot", "Explain black holes simply"],
inputs=msg,
label="Example Prompts" # Add label
)
# msg.focus() # Autoselect msg box - Sometimes causes issues, use if needed
# --- Launch ---
if __name__ == "__main__":
# Add share=True for a public link if running locally and want to share
# Add debug=True for more verbose logging during development
demo.queue() # Enable queue for better handling of multiple requests
demo.launch() |