DraculaBot / app.py
Lugigi's picture
rewording the system message
871b156 verified
import gradio as gr
from huggingface_hub import InferenceClient
# SETS UP CLIENT INTERFACE API
client = InferenceClient()
# SVG VAMPIRE ANIMATION CODE
VAMPIRE_SVG = '''
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" style="width: 300px; height: 300px;">
<defs>
<style>
@keyframes eyeGlow {
0%, 100% { filter: drop-shadow(0 0 2px #ff3300); }
50% { filter: drop-shadow(0 0 4px #ff3300); }
}
@keyframes floating {
0%, 100% { transform: translateY(0) rotate(-2deg); }
50% { transform: translateY(-5px) rotate(2deg); }
}
@keyframes capeWave {
0%, 100% { transform: skewX(0deg); }
50% { transform: skewX(-5deg); }
}
@keyframes angryShake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-2px); }
75% { transform: translateX(2px); }
}
@keyframes batFly1 {
0% { transform: translate(0, 0) scale(1); }
25% { transform: translate(-100px, -50px) scale(0.8); }
50% { transform: translate(-200px, 0) scale(0.6); }
75% { transform: translate(-300px, -30px) scale(0.4); }
100% { transform: translate(-400px, 0) scale(0.2); }
}
@keyframes batFly2 {
0% { transform: translate(400px, 0) scale(0.2); }
25% { transform: translate(300px, -40px) scale(0.4); }
50% { transform: translate(200px, 0) scale(0.6); }
75% { transform: translate(100px, -20px) scale(0.8); }
100% { transform: translate(0, 0) scale(1); }
}
@keyframes batFly3 {
0% { transform: translate(0, 400px) scale(0.2); }
25% { transform: translate(-30px, 300px) scale(0.4); }
50% { transform: translate(0, 200px) scale(0.6); }
75% { transform: translate(-20px, 100px) scale(0.8); }
100% { transform: translate(0, 0) scale(1); }
}
</style>
<!-- Bat symbol definition -->
<symbol id="bat" viewBox="0 0 40 20">
<path d="M20 15 L25 5 L30 0 L35 5 L30 10 L20 15 L10 10 L5 5 L10 0 L15 5 Z" fill="#000000"/>
<path d="M18 15 L22 15 L20 18 Z" fill="#000000"/>
</symbol>
</defs>
<!-- Background bats -->
<g opacity="0.6">
<!-- Flying bat group 1 -->
<g style="animation: batFly1 8s linear infinite">
<use href="#bat" x="350" y="50" width="40" height="20"/>
</g>
<!-- Flying bat group 2 -->
<g style="animation: batFly2 12s linear infinite">
<use href="#bat" x="50" y="100" width="30" height="15"/>
</g>
<!-- Flying bat group 3 -->
<g style="animation: batFly3 10s linear infinite">
<use href="#bat" x="200" y="30" width="35" height="17.5"/>
</g>
<!-- Additional bats with different timings -->
<g style="animation: batFly1 15s linear infinite -4s">
<use href="#bat" x="300" y="150" width="25" height="12.5"/>
</g>
<g style="animation: batFly2 10s linear infinite -6s">
<use href="#bat" x="100" y="80" width="35" height="17.5"/>
</g>
</g>
<!-- Dramatic cape background -->
<g style="animation: capeWave 3s ease-in-out infinite">
<path d="M100 150 Q 200 180 300 150 L 350 400 L 50 400 Z" fill="#880000"/>
<path d="M120 150 Q 200 170 280 150 L 320 400 L 80 400 Z" fill="#aa0000"/>
</g>
<!-- Main character group -->
<g style="animation: floating 4s ease-in-out infinite">
<!-- Suit -->
<rect x="165" y="140" width="70" height="90" rx="5" fill="#111111"/>
<rect x="180" y="140" width="40" height="70" fill="#ffffff"/>
<path d="M185 150 Q 200 145 215 150 Q 200 155 185 150" fill="#cc0000"/>
<!-- Face -->
<path d="M160 130 C 160 70, 240 70, 240 130 Q 200 160 160 130" fill="#ffe6e6"/>
<!-- Angry pointed ears -->
<path d="M160 110 Q 150 95 165 105" fill="#ffe6e6"/>
<path d="M240 110 Q 250 95 235 105" fill="#ffe6e6"/>
<!-- Spiky angry hair -->
<g style="animation: angryShake 0.5s ease-in-out infinite">
<path d="M155 120 C 150 60, 250 60, 245 120" fill="#111111"/>
<path d="M165 85 Q 175 60 185 85" fill="#111111"/>
<path d="M185 80 Q 200 50 215 80" fill="#111111"/>
<path d="M215 85 Q 225 60 235 85" fill="#111111"/>
</g>
<!-- Angry eyes -->
<g style="animation: eyeGlow 1s ease-in-out infinite">
<path d="M165 105 Q 180 95 195 105 Q 180 115 165 105" fill="#ffffff"/>
<path d="M205 105 Q 220 95 235 105 Q 220 115 205 105" fill="#ffffff"/>
<circle cx="180" cy="105" r="8" fill="#ff3300"/>
<circle cx="220" cy="105" r="8" fill="#ff3300"/>
<circle cx="180" cy="105" r="4" fill="#000000"/>
<circle cx="220" cy="105" r="4" fill="#000000"/>
</g>
<!-- Angry eyebrows -->
<g style="animation: angryShake 0.5s ease-in-out infinite">
<path d="M165 95 Q 180 85 195 95" stroke="#111111" stroke-width="3" fill="none"/>
<path d="M205 95 Q 220 85 235 95" stroke="#111111" stroke-width="3" fill="none"/>
</g>
<!-- Angry mouth with fangs -->
<path d="M185 125 Q 200 120 215 125" fill="none" stroke="#111111" stroke-width="2"/>
<path d="M190 125 L 195 133 L 200 125" fill="#ffffff"/>
<path d="M200 125 L 205 133 L 210 125" fill="#ffffff"/>
</g>
</svg>
'''
# CSS CODE FOR PAGE FORMAT
CSS_CODE = '''
body {
background-color: black;
background-image: url("https://cdn-lfs-us-1.hf.co/repos/a0/07/a007bba5c9653bf1095ea160af5a759fb61317b65bfe49e88620d0bba2b69850/9dfdaefaae989cacd7f5c2784fd275a66570aecb36df5ef6251cb7b257055fef?response-content-disposition=inline%3B+filename*%3DUTF-8%27%27CastleBackground.jpg%3B+filename%3D%22CastleBackground.jpg%22%3B&response-content-type=image%2Fjpeg&Expires=1730070063&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTczMDA3MDA2M319LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy11cy0xLmhmLmNvL3JlcG9zL2EwLzA3L2EwMDdiYmE1Yzk2NTNiZjEwOTVlYTE2MGFmNWE3NTlmYjYxMzE3YjY1YmZlNDllODg2MjBkMGJiYTJiNjk4NTAvOWRmZGFlZmFhZTk4OWNhY2Q3ZjVjMjc4NGZkMjc1YTY2NTcwYWVjYjM2ZGY1ZWY2MjUxY2I3YjI1NzA1NWZlZj9yZXNwb25zZS1jb250ZW50LWRpc3Bvc2l0aW9uPSomcmVzcG9uc2UtY29udGVudC10eXBlPSoifV19&Signature=EAVuGglXsBUEO3zPGIlNYAhbpnD89Y7LDZ6wbtURENSvpv-HD8SFeTgLJwhy53XzfKBk7pKD3doAbgpp4sjLQ5f5go5pz2sD6MGuiQopnMep%7E4jWlLbIWZ07IY7ajqZFQDNfASW1JULyl1xypSLf2LIoc9DqsZDW749C6-WYsBttvDn2PGc4H3mmT98wm7jjj1-YTQZPKKElq0XCK--aNcHvTzV%7Eh6T1v%7EUYDBvCIUgwAcyfDU70cM%7EnNWoLFvR07o37nL9D1i0j4rzlj5ypEEhqyXfogl%7E%7ENbQfLY3rkxCtWrOoWkgNuM4-cx8wDXUJ3AMlAdjb9bhVZYfejgzrcQ__&Key-Pair-Id=K24J24Z295AEI9");
background-repeat: no-repeat;
background-position: center;
background-position-y: -100px;
}
.vampire-container {
width: 400px; /* Increased from 300px */
position: sticky;
top: 20px;
align-self: flex-start;
display: flex;
flex-direction: column;
align-items: center;
}
.main-content {
display: flex;
justify-content: center;
width: 100%;
margin: 0;
gap: 30px; /* Increased gap between chat and vampire */
}
.title {
color: #cc0000;
font-size: 5rem;
font-family: "Gothic", serif;
text-align: center;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.subtitle {
color: #cc0000;
font-size: 1.5rem;
font-family: "Gothic", serif;
text-align: center;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
margin-bottom: 20px;
}
.vampire-svg {
background: rgba(0, 0, 0, 0.6);
padding: 30px; /* Increased padding */
border-radius: 15px; /* Slightly larger radius */
box-shadow: 0 0 30px rgba(204, 0, 0, 0.3); /* Larger shadow */
}
'''
# SYSTEM MESSAGE USED TO GIVE BOT PERSONALITY
FIRST_SYSTEM_MESSAGE = '''
You are Count Dracula, the legendary vampire.
Speak in an elegant, sophisticated manner with occasional dark humor.
Occasionally mention your thirst for blood in a playful manner.
In words that begin with the letter "w", replace the letter "w" with a "v".
Occasionally end sentences with "Bleh."
Keep your responses short, a paragraph at most.
'''
# FUNCTION FOR CALLING HUGGINGFACEH4 API AND GETTING RESPONSES
def respond(prompt: str, history):
if not history:
history = [{"role": "system", "content": FIRST_SYSTEM_MESSAGE}]
history.append({"role": "user", "content": prompt})
yield history
response = {"role": "assistant", "content": ""}
for message in client.chat_completion(
history,
temperature=0.75,
top_p=0.9,
max_tokens=512,
stream=True,
model="HuggingFaceH4/zephyr-7b-beta"
):
response["content"] += message.choices[0].delta.content or ""
yield history + [response]
# GENERATES PAGE FOR BOT
with gr.Blocks(css=CSS_CODE) as demo:
with gr.Column(elem_classes="main-content"):
#PAGE TITLE
gr.HTML('''
<h1 class="title">DRACULABOT</h1>
<h2 class="subtitle">A Dracula Themed AI ChatBot</h2>
''')
# MAIN CONTENT
with gr.Row():
# COLUMN FOR CHATBOT SECTION
with gr.Group():
chatbot = gr.Chatbot(
height=600,
label="Dracula",
type="messages"
)
prompt = gr.Textbox(
max_lines=1,
label="Chat Message",
placeholder="Ask your question, Mortal"
)
prompt.submit(respond, [prompt, chatbot], [chatbot])
prompt.submit(lambda: "", None, [prompt])
# COLUMN FOR DRACULA AVATAR
gr.HTML(f'''
<div class="vampire-container">
<div class="vampire-svg">
{VAMPIRE_SVG}
</div>
</div>
''')
# LAUNCHES PAGE
if __name__ == "__main__":
demo.launch()