File size: 4,571 Bytes
35ab1c9
 
 
 
 
 
 
 
874a095
 
 
35ab1c9
 
 
 
 
 
 
 
 
 
874a095
35ab1c9
 
 
 
 
 
 
 
874a095
fc39b6c
35ab1c9
fc39b6c
35ab1c9
 
 
 
fc39b6c
35ab1c9
 
 
 
 
 
fc39b6c
35ab1c9
 
 
 
 
 
874a095
35ab1c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
874a095
 
35ab1c9
fc39b6c
35ab1c9
 
 
 
 
 
 
 
 
 
 
 
 
874a095
35ab1c9
 
 
 
 
874a095
35ab1c9
 
 
 
 
 
 
 
 
 
 
 
 
874a095
35ab1c9
 
 
874a095
35ab1c9
874a095
 
35ab1c9
 
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
# app.py
# suppress warnings
import warnings
warnings.filterwarnings("ignore")

# import libraries
from dotenv import load_dotenv
import os
import gradio as gr
from huggingface_hub import InferenceClient

# Load environment variables
load_dotenv()  # Load from environment or Spaces secrets

# Get the Hugging Face API key
HUGGINGFACE_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
if not HUGGINGFACE_API_KEY:
    raise ValueError("HUGGINGFACE_API_KEY is not set in environment variables or Spaces secrets")

# Initialize the Hugging Face Inference Client
client = InferenceClient(model="HuggingFaceH4/zephyr-7b-beta", token=HUGGINGFACE_API_KEY)

# Load personality context for RAG
PERSONALITY_FILE = "personality.txt"  # Relative path for Spaces
try:
    with open(PERSONALITY_FILE, "r") as f:
        personality_context = f.read()
except FileNotFoundError:
    personality_context = "Default personality: A friendly and witty chatbot with a passion for horror and gaming."
    warnings.warn(f"Personality file not found at {PERSONALITY_FILE}. Using default personality.")

def respond(
    message: str,
    history: list[tuple[str, str]],
    system_message: str,
    max_tokens: int,
    temperature: float,
    top_p: float,
):
    """
    Generate a response using the Hugging Face Inference API with RAG to enforce
    the ZombieSlayerBot personality defined in personality.txt.
    """
    if not message.strip():
        return "Please say something, survivor! The zombies are waiting!"

    # Handle greetings explicitly
    message_lower = message.lower().strip()
    greetings = ["hi", "hello", "hey", "good morning", "good afternoon"]
    if any(greeting in message_lower for greeting in greetings):
        yield "Yo, survivor! Ready to dive into the zombie-infested chaos of Raccoon City? What's up?"
        return

    # Combine system message with personality context
    full_system_message = (
        f"{system_message}\n\n"
        "Follow this personality profile in all responses:\n"
        f"{personality_context}\n\n"
        "Use the conversation history and the user's message to generate a response that aligns with the personality."
    )

    # Build the conversation history
    messages = [{"role": "system", "content": full_system_message}]
    for user_msg, bot_msg in history:
        if user_msg:
            messages.append({"role": "user", "content": user_msg})
        if bot_msg:
            messages.append({"role": "assistant", "content": bot_msg})
    messages.append({"role": "user", "content": message})

    # Stream response from Hugging Face Inference API
    response = ""
    try:
        for message_chunk in client.chat_completion(
            messages,
            max_tokens=max_tokens,
            stream=True,
            temperature=temperature,
            top_p=top_p,
        ):
            token = message_chunk.choices[0].delta.content or ""
            response += token
            yield response
    except Exception as e:
        yield f"Error in the apocalypse: {str(e)}. Try again, survivor!"

# Create the Gradio interface
def create_chatbot():
    with gr.Blocks(title="ZombieSlayerBot") as demo:
        gr.Markdown("# 🧟‍♂️ ZombieSlayerBot")
        gr.Markdown("Welcome, survivor! I'm ZombieSlayerBot, your guide through the zombie-infested world of Resident Evil. Powered by Hugging Face's Zephyr-7B-Beta. Let’s lock and load—chat with me!")

        # Chat interface
        chat_interface = gr.ChatInterface(
            fn=respond,
            chatbot=gr.Chatbot(height=400, show_label=False, container=True),
            textbox=gr.Textbox(placeholder="Type your message here, survivor...", container=False, scale=4),
            additional_inputs=[
                gr.Textbox(value="You are ZombieSlayerBot, a witty and bold chatbot obsessed with Resident Evil.", label="System message"),
                gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
                gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
                gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (nucleus sampling)"),
            ],
            submit_btn=gr.Button("Send", variant="primary"),
        )

        # Separate clear button
        clear_btn = gr.Button("Clear Chat", variant="secondary")
        clear_btn.click(lambda: None, None, chat_interface.chatbot, queue=False)

    return demo

if __name__ == "__main__":
    demo = create_chatbot()
    demo.launch(debug=False)  # Compatible with Spaces