|
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 |
|
|
|
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: |
|
|
|
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.""" |
|
|
|
|
|
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}) |
|
|
|
|
|
response = self.openai_client.chat.completions.create( |
|
model="gpt-4o-mini", |
|
messages=messages, |
|
temperature=0.9, |
|
max_tokens=150 |
|
) |
|
|
|
|
|
ai_message = response.choices[0].message.content |
|
final_response = "" |
|
|
|
|
|
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\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 |
|
|
|
|
|
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") |
|
|
|
|
|
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 |
|
|
|
|
|
if __name__ == "__main__": |
|
demo = create_interface() |
|
demo.launch() |