Spaces:
Running
Running
# Import the Gradio library for creating the web interface | |
import gradio as gr | |
# Import the InferenceClient from huggingface_hub to interact with the language model | |
from huggingface_hub import InferenceClient | |
# --- Configuration Constants --- | |
FIXED_MAX_TOKENS = 1000 | |
# --- Initialize the InferenceClient --- | |
API_BASE_URL = "https://vulture-awake-probably.ngrok-free.app/v1/chat/completions" | |
try: | |
client = InferenceClient(base_url=API_BASE_URL) | |
print(f"InferenceClient initialized with base_url: {API_BASE_URL}") | |
except Exception as e: | |
print(f"Error initializing InferenceClient with base_url '{API_BASE_URL}': {e}") | |
raise RuntimeError( | |
"Could not initialize InferenceClient. " | |
f"Please check the API base URL ('{API_BASE_URL}') and ensure the server is accessible. " | |
f"Error: {e}" | |
) | |
# --- Core Chatbot Logic --- | |
def respond(message, history): | |
messages = [] | |
for user_message, ai_message in history: | |
if user_message: | |
messages.append({"role": "user", "content": user_message}) | |
if ai_message: | |
messages.append({"role": "assistant", "content": ai_message}) | |
messages.append({"role": "user", "content": message}) | |
response_text = "" | |
try: | |
stream = client.chat_completion( | |
messages=messages, | |
max_tokens=FIXED_MAX_TOKENS, | |
stream=True, | |
) | |
for chunk in stream: | |
if chunk.choices and chunk.choices[0].delta and chunk.choices[0].delta.content is not None: | |
token = chunk.choices[0].delta.content | |
response_text += token | |
yield response_text | |
except Exception as e: | |
error_message = f"An error occurred during model inference: {e}" | |
print(error_message) | |
yield error_message | |
# --- Gradio Interface Definition --- | |
# URL for the header image | |
header_image_path = "https://cdn-uploads.huggingface.co/production/uploads/6540a02d1389943fef4d2640/j61iZTDaK9g0UW3aWGwWi.gif" | |
# Ko-fi widget script (original) | |
kofi_script_original = """ | |
<script src='https://storage.ko-fi.com/cdn/scripts/overlay-widget.js'></script> | |
<script> | |
kofiWidgetOverlay.draw('sonnydesorbo', { | |
'type': 'floating-chat', | |
'floating-chat.donateButton.text': 'Support me', | |
'floating-chat.donateButton.background-color': '#00b9fe', | |
'floating-chat.donateButton.text-color': '#fff' | |
}); | |
</script> | |
""" | |
# Ko-fi button HTML | |
kofi_button_html = """ | |
<div style="text-align: center; padding: 10px 20px 20px 20px;"> | |
<a href='https://ko-fi.com/Z8Z51E5TIG' target='_blank'> | |
<img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi5.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /> | |
</a> | |
</div> | |
""" | |
# HTML, CSS, and JavaScript for Matrix Rain | |
matrix_rain_html_script = """ | |
<canvas id="matrixCanvas"></canvas> | |
<style> | |
body { | |
/* overflow: hidden; */ /* Might hide Gradio scrollbars, be careful */ | |
/* Gradio manages its own background, so direct body changes might be tricky. | |
The canvas will be fixed behind everything. */ | |
} | |
#matrixCanvas { | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
z-index: -1; /* Place it behind all Gradio content */ | |
display: block; | |
} | |
/* Ensure Gradio's main content area is above the canvas and has a transparent background | |
if you want the rain to be visible *through* it, or a solid dark background | |
if you want it *around* it. Gradio theming should handle the component backgrounds. | |
*/ | |
gradio-app > .main, gradio-app > .main > .wrap, gradio-app { /* Attempt to make Gradio app background transparent */ | |
/* background: transparent !important; */ /* This can be aggressive, use with caution */ | |
} | |
/* You might need to adjust specific Gradio component backgrounds if they are not dark by default with the theme */ | |
.gradio-container { | |
/* background: transparent !important; */ /* Example */ | |
} | |
</style> | |
<script> | |
document.addEventListener('DOMContentLoaded', (event) => { | |
const canvas = document.getElementById('matrixCanvas'); | |
if (!canvas) { | |
console.error("Matrix canvas not found"); | |
return; | |
} | |
const ctx = canvas.getContext('2d'); | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
const katakana = 'アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッン'; | |
const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; | |
const nums = '0123456789'; | |
const characters = katakana + latin + nums; | |
const fontSize = 16; | |
let columns = Math.floor(canvas.width / fontSize); | |
let drops = []; | |
function initializeDrops() { | |
columns = Math.floor(canvas.width / fontSize); | |
drops = []; | |
for (let x = 0; x < columns; x++) { | |
drops[x] = 1 + Math.floor(Math.random() * (canvas.height / fontSize)); | |
} | |
} | |
initializeDrops(); | |
function drawMatrix() { | |
ctx.fillStyle = 'rgba(0, 0, 0, 0.04)'; // Black BG for the canvas with a little blur | |
ctx.fillRect(0, 0, canvas.width, canvas.height); | |
// Use a color that fits the dark theme, e.g., a neon green or the theme's primary color | |
// For Gradio, you might try to pick up CSS variables if available, or hardcode. | |
ctx.fillStyle = '#0F0'; // Classic green | |
// Example: Try to use Gradio's primary color if possible (might require more complex JS) | |
// const gradioPrimaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-500') || '#0F0'; | |
// ctx.fillStyle = gradioPrimaryColor; | |
ctx.font = fontSize + 'px monospace'; | |
for (let i = 0; i < drops.length; i++) { | |
const text = characters.charAt(Math.floor(Math.random() * characters.length)); | |
ctx.fillText(text, i * fontSize, drops[i] * fontSize); | |
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) { | |
drops[i] = 0; | |
} | |
drops[i]++; | |
} | |
} | |
let matrixInterval = setInterval(drawMatrix, 45); // Adjusted speed | |
window.addEventListener('resize', () => { | |
const oldWidth = canvas.width; | |
const oldHeight = canvas.height; | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
if (canvas.width !== oldWidth || canvas.height !== oldHeight) { | |
initializeDrops(); | |
} | |
}); | |
// Optional: A slight delay for Gradio to finish rendering before starting matrix | |
// setTimeout(() => { | |
// if (matrixInterval) clearInterval(matrixInterval); | |
// initializeDrops(); | |
// matrixInterval = setInterval(drawMatrix, 45); | |
// }, 500); | |
}); | |
</script> | |
""" | |
# Combine Ko-fi script with Matrix Rain script for the 'head' | |
combined_head_script = kofi_script_original + matrix_rain_html_script | |
# Create a Gradio Blocks layout | |
# Use a dark theme and add the combined scripts to the head | |
# theme = gr.themes.Soft() # Original theme | |
theme = gr.themes.Base(primary_hue=gr.themes.colors.green, neutral_hue=gr.themes.colors.slate).dark() # Example dark theme | |
with gr.Blocks(theme=theme, head=combined_head_script) as demo: | |
# Display an image at the top | |
gr.Image( | |
value=header_image_path, | |
label="Chatbot Header", | |
show_label=False, | |
interactive=False, | |
height=150, | |
elem_id="chatbot-logo" | |
) | |
# Create the chat interface component | |
gr.ChatInterface( | |
fn=respond, | |
chatbot=gr.Chatbot( | |
height=650, | |
# elem_id="chatbot_messages_container" # You can add an ID for more specific CSS | |
), | |
# title="XORTRON AI", # You can set a title | |
# description="Engage with the digital rain." # And a description | |
) | |
# Add the Ko-fi button at the bottom | |
gr.HTML(kofi_button_html) | |
# --- Application Entry Point --- | |
if __name__ == "__main__": | |
try: | |
demo.launch(show_api=False, share=False) | |
except NameError as ne: | |
print(f"Gradio demo could not be launched. 'client' might not have been initialized: {ne}") | |
except RuntimeError as re: | |
print(f"Gradio demo could not be launched due to an error during client initialization: {re}") | |
except Exception as e: | |
print(f"An unexpected error occurred when trying to launch Gradio demo: {e}") |