Spaces:
Sleeping
Sleeping
| 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() |