import gradio as gr from openai import OpenAI import requests import json from typing import List, Dict, Optional class GifChatBot: def __init__(self): self.openai_client = None self.giphy_key = None self.chat_history = [] def setup_keys(self, openai_key: str, giphy_key: str) -> str: """Initialize API clients with user's keys""" try: self.openai_client = OpenAI(api_key=openai_key) self.giphy_key = giphy_key # Test the keys self._test_giphy_key() self._test_openai_key() return "✅ Setup successful! Let's chat!" except Exception as e: return f"❌ Error setting up: {str(e)}" def _test_giphy_key(self): """Test if GIPHY key is valid""" response = requests.get( "https://api.giphy.com/v1/gifs/trending", params={"api_key": self.giphy_key, "limit": 1} ) if response.status_code != 200: raise Exception("Invalid GIPHY API key") def _test_openai_key(self): """Test if OpenAI key is valid""" try: self.openai_client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "test"}], max_tokens=5 ) except Exception: raise Exception("Invalid OpenAI API key") def get_gif(self, search_query: str) -> Optional[str]: """Search GIPHY for a relevant GIF""" try: response = requests.get( "https://api.giphy.com/v1/gifs/search", params={ "api_key": self.giphy_key, "q": search_query, "limit": 10, "rating": "pg-13" } ) if response.status_code == 200: data = response.json() if data["data"]: import random gif = random.choice(data["data"]) return gif["images"]["original"]["url"] except Exception as e: print(f"GIPHY error: {e}") return None def chat(self, message: str, history: List[List[str]]) -> tuple[str, List[List[str]]]: """Main chat function with GIF support""" if not self.openai_client or not self.giphy_key: return "Please set up your API keys first!", history try: # Create the system message that encourages proactive GIF usage system_message = """You are a fun, internet-savvy friend who loves expressing yourself through GIFs! You can and should proactively use GIFs when appropriate to make the conversation more engaging. To use a GIF, simply include [GIF: description] in your message where you want the GIF to appear. For example: "That's amazing! [GIF: mind blown explosion] I can't believe it!" Keep your responses conversational and natural, and use GIFs to enhance emotional expression or reactions. Don't overuse GIFs - use them naturally like a real person would in chat.""" # Prepare conversation history messages = [{"role": "system", "content": system_message}] for h in history: messages.extend([ {"role": "user", "content": h[0]}, {"role": "assistant", "content": h[1]} ]) messages.append({"role": "user", "content": message}) # Get AI response response = self.openai_client.chat.completions.create( model="gpt-4o-mini", messages=messages, temperature=0.9, max_tokens=150 ) # Process response and insert GIFs ai_message = response.choices[0].message.content final_response = "" # Split by GIF markers and process parts = ai_message.split("[GIF:") final_response += parts[0] for part in parts[1:]: gif_desc_end = part.find("]") if gif_desc_end != -1: gif_desc = part[:gif_desc_end].strip() gif_url = self.get_gif(gif_desc) if gif_url: final_response += f"\n![GIF]({gif_url})\n" final_response += part[gif_desc_end + 1:] history.append([message, final_response]) return final_response, history except Exception as e: return f"Oops! Something went wrong: {str(e)}", history # Create Gradio interface def create_interface(): bot = GifChatBot() with gr.Blocks() as interface: gr.Markdown(""" # Fun AI Friend with GIFs! 🎉 First, enter your API keys below to get started. Then chat away! """) with gr.Row(): openai_key = gr.Textbox( label="OpenAI API Key", placeholder="sk-...", type="password" ) giphy_key = gr.Textbox( label="GIPHY API Key", placeholder="Enter your GIPHY API key", type="password" ) setup_button = gr.Button("Set up Keys") setup_status = gr.Textbox(label="Setup Status") chatbot = gr.Chatbot( label="Chat", bubble_full_width=False, show_label=False, height=400 ) msg = gr.Textbox( label="Type your message", placeholder="Say something...", show_label=False ) clear = gr.Button("Clear Chat") # Set up event handlers setup_button.click( bot.setup_keys, inputs=[openai_key, giphy_key], outputs=setup_status ) msg.submit( bot.chat, inputs=[msg, chatbot], outputs=[msg, chatbot] ) clear.click(lambda: None, None, chatbot) gr.Markdown(""" ### Notes: - The AI will naturally use GIFs when appropriate in conversation - Your API keys are never stored and are only used for this session - Have fun chatting! 🎈 """) return interface # Launch the app if __name__ == "__main__": demo = create_interface() demo.launch()