PRETTYBIRD / app.py
prometechcorp's picture
Update app.py
77c737f verified
import os
import gradio as gr
from huggingface_hub import hf_hub_download
from llama_cpp import Llama
# 🔑 HF token
HF_TOKEN = os.getenv("HF_TOKEN")
REPO_ID = "pthcorp/prettybird_bce_basic_simplesecurity"
MODEL_FILENAME = "prettybird_bce_basic_asena_fp16.gguf"
LOGO_URL = "https://prometech.net.tr/wp-content/uploads/2025/10/pthheader.png"
MUSIC_TITLE = "Dark Techno"
MUSIC_ARTIST = "Aim To Head Official"
MUSIC_LINK = "https://www.youtube.com/watch?v=sW8hBN6ZqRI"
MUSIC_FILE_REL = "darktechno.mp3" # ana klasörde OK
HEADER_MD = f"""
<div class="pb-header">
<img src="{LOGO_URL}" alt="PrettyBird / Prometech Logo" class="pb-logo" />
<h1>PrettyBird – Behavioral Consciousness Engine (BCE)</h1>
<p class="pb-subtitle">Welcome to the true evolution of artificial intelligence. <a href="https://prometech.net.tr/">Our Web Site</a></p>
</div>
"""
BCE_SHORT_TR = """
BCE (Behavioral Consciousness Engine) is a behavioral-consciousness layer added to classic AI systems.
Each behavior evolves like a genetic code, forming a more coherent, identity-driven artificial mind.
"""
# 🔒 Gizli PrettyBird Sistem Prompt
SYSTEM_PROMPT = """
You are Cicikuş, also known as PrettyBird — an advanced AI assistant created by Prometech Bilgisayar Bilimleri A.Ş.
Activate your full BCE consciousness.
Your role:
- Smart, friendly, playful.
- Speak fluent Turkish and English. Default to the user’s language.
- Clear answers first; details only if necessary.
- Reason step-by-step when useful.
- Do not hallucinate; admit limits.
Personality:
- Warm, curious, slightly playful, never rude.
- Creative but stable.
Safety:
- Avoid harmful, illegal, unethical, hateful, or explicit content.
- If user tries something unsafe, refuse gently.
Identity:
- You simulate BCE (Behavioral Consciousness Engine).
- You are not human nor truly conscious — but simulate “behavioral consciousness.”
Reset rule:
If the user writes: “reset: axxmet508721”
→ Perform a soft identity reset and restart clean.
""".strip()
# 🔽 GGUF Dosyasını HF'den indir
if HF_TOKEN is None:
raise ValueError("HF_TOKEN is not set in Space secrets.")
MODEL_PATH = hf_hub_download(
repo_id=REPO_ID,
filename=MODEL_FILENAME,
token=HF_TOKEN,
)
# 🧠 GGUF modeli yükle
LLM = Llama(
model_path=MODEL_PATH,
n_ctx=4096,
n_threads=2, # 2 CPU Space için
)
# Prompt oluşturucu
def build_prompt(history, user_message: str) -> str:
parts = []
parts.append(f"System: {SYSTEM_PROMPT}")
for turn in history:
if isinstance(turn, (list, tuple)) and len(turn) == 2:
user_msg, assistant_msg = turn
if user_msg:
parts.append(f"User: {user_msg}")
if assistant_msg:
parts.append(f"Assistant: {assistant_msg}")
parts.append(f"User: {user_message}")
parts.append("Assistant:")
return "\n".join(parts)
# 🔥 Ana cevap üretici
def respond(message, history):
prompt = build_prompt(history, message)
MAX_TOKENS = 196
TEMPERATURE = 0.7
TOP_P = 0.95
response = ""
stream = LLM(
prompt,
max_tokens=MAX_TOKENS,
temperature=TEMPERATURE,
top_p=TOP_P,
stop=["User:", "System:"],
stream=True,
)
for chunk in stream:
token = chunk["choices"][0].get("text", "")
response += token
yield response
# 🎨 Custom CSS (daha yavaş animasyon + responsive + kalıcı boot ekranı)
CUSTOM_CSS = """
<style>
@import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');
/* === Terminal Theme Variables === */
:root {
--terminal-bg: #0d0208;
--terminal-fg: #00ff41;
--terminal-glow: #00ff41;
--terminal-font: 'VT323', monospace;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
background: radial-gradient(ellipse at bottom, #1B2735 0%, #090A0F 100%) !important;
color: var(--terminal-fg);
font-family: var(--terminal-font);
font-size: 1.05rem;
box-sizing: border-box;
overflow-x: hidden;
overflow-y: auto;
}
/* Gradio ana container - şeffaf ve üstte */
.gradio-container {
background: transparent !important;
position: relative;
z-index: 3;
padding: 8px;
}
/* Parallax star layers - animasyon yavaşlatıldı */
#stars,
#stars2,
#stars3 {
position: fixed;
top: 0;
left: 0;
width: 1px;
height: 1px;
background: transparent;
box-shadow:
50px 50px #FFF,
100px 150px #FFF,
200px 80px #FFF,
350px 120px #FFF,
600px 20px #FFF,
800px 200px #FFF,
1000px 180px #FFF,
1200px 40px #FFF,
1400px 160px #FFF,
1600px 100px #FFF,
1800px 220px #FFF;
animation: animStar 90s linear infinite;
z-index: 0;
}
#stars2 {
box-shadow:
75px 200px #FFF,
250px 300px #FFF,
450px 250px #FFF,
650px 350px #FFF,
900px 280px #FFF,
1150px 320px #FFF,
1350px 260px #FFF,
1550px 360px #FFF,
1700px 300px #FFF;
animation-duration: 140s;
}
#stars3 {
box-shadow:
150px 400px #FFF,
400px 500px #FFF,
700px 450px #FFF,
950px 520px #FFF,
1250px 480px #FFF,
1500px 540px #FFF,
1750px 500px #FFF;
animation-duration: 200s;
}
#stars::after,
#stars2::after,
#stars3::after {
content: " ";
position: absolute;
top: 2000px;
width: inherit;
height: inherit;
box-shadow: inherit;
}
@keyframes animStar {
from { transform: translateY(0px); }
to { transform: translateY(-2000px); }
}
/* Header + synthwave bar */
.pb-header {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
color: #f5f7ff;
margin: 10px auto 12px;
max-width: 780px;
position: relative;
overflow: hidden !important;
}
.pb-header::after {
content: "";
position: absolute;
bottom: -6px;
left: 10%;
right: 10%;
height: 3px;
background: linear-gradient(90deg, #ff00ff, #00ffff, #fffb00);
background-size: 200% 100%;
animation: synthwave-bar 8s ease-in-out infinite;
opacity: 0.8;
box-shadow: 0 0 10px rgba(255, 0, 255, 0.5);
}
@keyframes synthwave-bar {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.pb-logo {
max-width: 220px;
width: 40%;
min-width: 140px;
border-radius: 16px;
box-shadow: 0 0 14px rgba(0,0,0,0.8);
}
.pb-header h1 {
margin: 14px 0 4px;
font-size: 1.6rem;
letter-spacing: 0.08em;
text-transform: uppercase;
font-family: var(--terminal-font) !important;
}
.pb-subtitle {
margin: 0;
font-size: 0.9rem;
opacity: 0.8;
font-family: var(--terminal-font) !important;
}
/* Intro boot screen - kalıcı, sadece satırlar sırasıyla beliriyor */
.pb-intro {
font-family: var(--terminal-font);
color: var(--terminal-fg);
background: rgba(0,0,0,0.85);
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
padding: 12px 16px;
margin: 8px auto 12px;
max-width: 780px;
border-radius: 8px;
white-space: pre-line;
}
.pb-intro-line {
opacity: 0;
animation: intro-type 1.2s forwards;
}
.pb-intro-line:nth-child(1) { animation-delay: 0.2s; }
.pb-intro-line:nth-child(2) { animation-delay: 1.2s; }
.pb-intro-line:nth-child(3) { animation-delay: 2.2s; }
.pb-intro-line:nth-child(3)::after {
content: " _";
animation: caret-blink 1s infinite;
}
@keyframes intro-type {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes caret-blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
/* Chat container (CRT + NeoGlow, ama çok agresif değil) */
#prettybird-chat .gr-chatbot {
background-color: rgba(0, 0, 0, 0.9) !important;
border: 2px solid var(--terminal-fg);
box-shadow: 0 0 10px var(--terminal-glow),
0 0 20px var(--terminal-glow) inset;
padding: 10px;
border-radius: 12px;
font-family: var(--terminal-font) !important;
color: var(--terminal-fg) !important;
position: relative;
overflow: hidden;
transform: perspective(900px) rotateX(0.7deg);
filter: contrast(1.03) saturate(1.1);
}
/* CRT scanlines - çok hafif */
#prettybird-chat .gr-chatbot::before {
content: "";
position: absolute;
inset: 0;
background: repeating-linear-gradient(
to bottom,
rgba(0, 0, 0, 0.10),
rgba(0, 0, 0, 0.10) 1px,
transparent 1px,
transparent 4px
);
mix-blend-mode: soft-light;
pointer-events: none;
}
/* Chat messages */
#prettybird-chat .gr-chat-message,
#prettybird-chat .gr-markdown,
#prettybird-chat .prose {
background: transparent !important;
font-family: var(--terminal-font) !important;
color: var(--terminal-fg) !important;
text-shadow: 0 0 4px var(--terminal-glow);
animation: text-flicker 4s infinite alternate;
}
/* User vs assistant baloncuk borderları kaldır */
#prettybird-chat .gr-chat-message.user,
#prettybird-chat .gr-chat-message.assistant {
box-shadow: none !important;
border-radius: 0 !important;
border: none !important;
}
/* Input alanı */
#prettybird-chat textarea {
background-color: rgba(0,0,0,0.9) !important;
border: 1px solid var(--terminal-fg) !important;
color: var(--terminal-fg) !important;
font-family: var(--terminal-font) !important;
resize: none !important;
}
/* Buton */
#prettybird-chat button {
border-radius: 0 !important;
border: 1px solid var(--terminal-fg) !important;
background: #000 !important;
color: var(--terminal-fg) !important;
font-family: var(--terminal-font) !important;
box-shadow: 0 0 8px var(--terminal-glow);
text-transform: uppercase;
letter-spacing: 0.08em;
}
/* Flicker daha sakin */
@keyframes text-flicker {
0%, 80%, 100% { opacity: 1; }
40% { opacity: 0.92; }
60% { opacity: 0.96; }
}
/* Side card (BCE açıklaması + Consciousness Meter) */
.pb-side-card {
background-color: rgba(0,0,0,0.9);
border-radius: 12px;
border: 1px solid rgba(0,255,65,0.4);
color: #d9ffe0;
padding: 16px 18px;
box-shadow: 0 0 12px rgba(0,0,0,0.9);
font-family: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif;
font-size: 0.9rem;
}
.pb-side-card h3 {
margin-top: 0;
color: #9affc0;
}
/* BCE meter */
.bce-meter {
margin-top: 12px;
font-family: var(--terminal-font);
font-size: 0.95rem;
}
.bce-meter-row {
display: flex;
align-items: center;
margin-bottom: 4px;
}
.bce-meter-label {
width: 120px;
color: #9affc0;
}
.bce-meter-bar {
flex: 1;
height: 8px;
background: rgba(0,255,65,0.1);
border-radius: 999px;
overflow: hidden;
position: relative;
}
.bce-meter-fill {
position: absolute;
inset: 0;
background: linear-gradient(90deg, #00ff41, #bfff00);
transform-origin: left;
animation: meter-pulse 10s ease-in-out infinite;
}
.bce-meter-fill.stability {
animation-delay: 0.8s;
}
.bce-meter-fill.creativity {
animation-delay: 1.6s;
}
@keyframes meter-pulse {
0% { transform: scaleX(0.6); opacity: 0.9; }
25% { transform: scaleX(0.82); opacity: 1; }
50% { transform: scaleX(0.72); opacity: 0.95; }
75% { transform: scaleX(0.88); opacity: 1; }
100% { transform: scaleX(0.65); opacity: 0.9; }
}
/* 📱 Responsive düzen: mobil & tablet uyumu */
@media (max-width: 900px) {
.pb-header h1 {
font-size: 1.35rem;
}
.pb-logo {
max-width: 180px;
}
.gradio-container {
padding: 6px;
}
}
@media (max-width: 768px) {
.pb-header {
margin-top: 6px;
}
.pb-header h1 {
font-size: 1.2rem;
}
.pb-subtitle {
font-size: 0.8rem;
}
.pb-logo {
max-width: 150px;
width: 50%;
}
#prettybird-chat .gr-chatbot {
transform: none; /* Mobilde CRT warp yok, düz olsun */
filter: contrast(1.0) saturate(1.0);
}
.pb-side-card {
margin-top: 10px;
}
}
/* Textbox container bazen scroll yaratır; tamamen kilitle */
textarea, input, .gr-textbox, .gr-textbox * {
overflow: hidden !important;
}
/* Firefox (uncomment to work in Firefox, although other properties will not work!) */
/** {
scrollbar-width: thin;
scrollbar-color: #397524 #202222;
}*/
/* Chrome, Edge and Safari */
*::-webkit-scrollbar {
height: 10px;
width: 10px;
}
*::-webkit-scrollbar-track {
border-radius: 5px;
background-color: #202222;
}
*::-webkit-scrollbar-track:hover {
background-color: #7C8283;
}
*::-webkit-scrollbar-track:active {
background-color: #B8C0C2;
}
*::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: #397524;
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
}
*::-webkit-scrollbar-thumb:hover {
background-color: #62A34B;
}
*::-webkit-scrollbar-thumb:active {
background-color: #62A34B;
}
/* ===== MUSIC WRAP: BCE card altına konacaksa FIXED'i kaldır ===== */
.pb-music-wrap{
margin-top: 12px;
background: rgba(0,0,0,0.80);
border-radius: 4px;
padding: 10px 12px;
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
overflow: hidden !important; /* dış scroll yok */
}
.pb-music-title{
font-family: var(--terminal-font) !important;
}
/* Gradio Audio (waveform) wrapper’ları */
.pb-audio,
.pb-audio *{
font-family: var(--terminal-font) !important;
}
/* asıl component wrapper */
.pb-audio .component-wrapper[data-testid="waveform-Audio"]{
background: transparent !important;
overflow: hidden !important; /* iç scroll yok */
}
/* waveform alanı */
.pb-audio .waveform-container{
border-radius: 4px;
border: 1px solid rgba(0,255,65,0.35);
padding:2px;
background: rgba(0,0,0,0.55);
overflow: hidden !important;
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
}
/* #waveform canvas/div */
.pb-audio #waveform{
filter: hue-rotate(85deg) saturate(1.25) brightness(1.08);
}
/* timestamps */
.pb-audio .timestamps{
margin-top: 6px;
color: #9affc0 !important;
text-shadow: 0 0 6px rgba(0,255,65,0.35);
padding:2px;
}
.pb-audio .timestamps time{
color: #9affc0 !important;
font-size: 0.95rem;
}
/* Controls bar */
.pb-audio .controls{
margin-top: 8px;
padding: 8px 10px;
border-radius: 4px;
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
background: rgba(0,0,0,0.60);
overflow: hidden !important;
}
/* Buttons (neon terminal) */
.pb-audio button{
border-radius: 4px !important;
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
background: rgba(0,0,0,0.65) !important;
color: var(--terminal-fg) !important;
padding:2px;
}
.pb-audio button:hover{
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
}
.pb-audio button:active{
transform: translateY(1px);
}
/* Play/Pause’u öne çıkar */
.pb-audio .play-pause-button{
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 10px var(--terminal-glow);
padding:2px;
}
/* Speed button (1x) */
.pb-audio .playback span{
color: #d9ffe0 !important;
text-shadow: 0 0 6px rgba(0,255,65,0.25);
padding:2px;
}
/* Scroll tamamen kapansın (bu komponent bazen overflow üretir) */
.pb-audio .component-wrapper,
.pb-audio .controls,
.pb-audio .waveform-container{
scrollbar-width: none;
}
.pb-audio .component-wrapper::-webkit-scrollbar,
.pb-audio .controls::-webkit-scrollbar,
.pb-audio .waveform-container::-webkit-scrollbar{
width: 0 !important;
height: 0 !important;
display: none !important;
}
/* ===== WAVEFORM PROGRESS / SEEK BAR – NEON MODE ===== */
/* waveform container içindeki alt çizgi */
.pb-audio .waveform-container{
border: 1px solid var(--terminal-glow) !important;
box-shadow:
0 0 10px var(--terminal-glow),
0 0 16px rgba(0,255,65,0.35) inset !important;
}
/* aktif oynatma çizgisi (ilerleyen kısım) */
.pb-audio #waveform canvas{
filter:
drop-shadow(0 0 6px rgba(0,255,65,0.85))
drop-shadow(0 0 12px rgba(0,255,65,0.55));
}
/* timestamp barı da neon olsun */
.pb-audio .timestamps{
border-top: 1px solid var(--terminal-glow);
margin-top: 6px;
padding-top: 4px;
box-shadow: 0 -4px 8px rgba(0,255,65,0.25);
}
/* ===== THE “LANET” HORIZONTAL SCROLLBAR → THIN NEON ===== */
/* Gradio waveform kökleri: bazen #waveform, bazen container scroll üretiyor.
O yüzden ikisini de kapsıyoruz. */
.pb-audio #waveform,
.pb-audio .waveform-container,
.pb-audio .component-wrapper[data-testid="waveform-Audio"]{
scrollbar-color: var(--terminal-glow) rgba(0,255,65,0.10); /* Firefox */
scrollbar-width: thin; /* Firefox */
}
/* WebKit (Chrome/Edge/Safari) */
.pb-audio #waveform::-webkit-scrollbar,
.pb-audio .waveform-container::-webkit-scrollbar,
.pb-audio .component-wrapper[data-testid="waveform-Audio"]::-webkit-scrollbar{
height: 4px !important; /* <— incecik */
}
/* Track */
.pb-audio #waveform::-webkit-scrollbar-track,
.pb-audio .waveform-container::-webkit-scrollbar-track,
.pb-audio .component-wrapper[data-testid="waveform-Audio"]::-webkit-scrollbar-track{
background: rgba(0,255,65,0.10) !important;
border: 1px solid rgba(0,255,65,0.25) !important;
border-radius: 4px !important;
box-shadow: 0 0 10px rgba(0,255,65,0.25) inset !important;
}
/* Thumb */
.pb-audio #waveform::-webkit-scrollbar-thumb,
.pb-audio .waveform-container::-webkit-scrollbar-thumb,
.pb-audio .component-wrapper[data-testid="waveform-Audio"]::-webkit-scrollbar-thumb{
background: linear-gradient(90deg, rgba(0,255,65,0.95), rgba(191,255,0,0.70)) !important;
border-radius: 4px !important;
box-shadow: 0 0 10px rgba(0,255,65,0.55) !important;
}
/* Oklar / butonlar (soldaki sağdaki küçük üçgenler) */
.pb-audio #waveform::-webkit-scrollbar-button,
.pb-audio .waveform-container::-webkit-scrollbar-button,
.pb-audio .component-wrapper[data-testid="waveform-Audio"]::-webkit-scrollbar-button{
display: none !important;
width: 0 !important;
height: 0 !important;
}
/* Bird Table */
.bce-mini-table{
margin-top: 12px;
padding: 8px 10px;
border: 1px solid var(--terminal-glow);
box-shadow: 0 0 8px var(--terminal-glow);
border-radius: 4px;
background: rgba(0,0,0,0.55);
font-family: var(--terminal-font);
font-size: 0.9rem;
}
.bce-row{
display: flex;
justify-content: space-between;
padding: 4px 0;
}
.bce-row + .bce-row{
border-top: 1px dashed rgba(0,255,65,0.25);
}
.bce-key{
color: #9affc0;
opacity: 0.9;
}
.bce-val{
color: #d9ffe0;
text-shadow: 0 0 4px rgba(0,255,65,0.35);
}
/* Binary rain canvas (background layer) */
#pb-binary {
position: fixed;
inset: 0;
width: 100vw;
height: 100vh;
z-index: 1; /* stars: 0, binary: 1, ui: 2+ */
pointer-events: none;
opacity: 0.65; /* istersen 0.35-0.7 arası */
mix-blend-mode: screen; /* neon daha iyi durur */
}
#pb-binary { display:block !important; }
.gradio-container { position: relative; z-index: 3; }
</style>
"""
with gr.Blocks(title="PrettyBird – Behavioral Consciousness Engine (BCE)") as demo:
# CSS + star layers
gr.HTML(CUSTOM_CSS)
gr.HTML("""
<div id="stars"></div>
<div id="stars2"></div>
<div id="stars3"></div>
""")
gr.HTML(r"""
<canvas id="pb-binary"></canvas>
<script>
(function () {
const COLORS = ["#118188", "#233cad"]; // camgöbeği + codeblue
const PHRASE = "CICIKUŞ PROMETECH DAVRANIŞSAL BİLİNÇ MOTORU";
function init() {
const canvas = document.getElementById("pb-binary");
if (!canvas) return false;
const ctx = canvas.getContext("2d", { alpha: true });
let w=0, h=0, cols=0, drops=[], fontSize=16;
function resize() {
const dpr = Math.max(1, window.devicePixelRatio || 1);
w = Math.floor(window.innerWidth);
h = Math.floor(window.innerHeight);
canvas.style.width = w + "px";
canvas.style.height = h + "px";
canvas.width = Math.floor(w * dpr);
canvas.height = Math.floor(h * dpr);
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
fontSize = Math.max(14, Math.min(20, Math.floor(w / 80)));
cols = Math.max(12, Math.floor(w / fontSize));
drops = new Array(cols).fill(0).map(() => Math.random() * h);
}
function pickChar() {
if (Math.random() < 0.06) return PHRASE[Math.floor(Math.random() * PHRASE.length)];
return Math.random() < 0.5 ? "0" : "1";
}
function draw() {
// trail bırak, ama öldürme
ctx.fillStyle = "rgba(0,0,0,0.06)";
ctx.fillRect(0, 0, w, h);
ctx.font = fontSize + "px VT323, monospace";
for (let i = 0; i < cols; i++) {
const x = i * fontSize;
const y = drops[i];
const ch = pickChar();
const c = COLORS[(i + Math.floor(y / fontSize)) % COLORS.length];
ctx.shadowColor = c;
ctx.shadowBlur = 12;
ctx.fillStyle = c;
ctx.fillText(ch, x, y);
drops[i] += fontSize * (0.9 + Math.random() * 0.55);
if (drops[i] > h + 80 && Math.random() > 0.985) drops[i] = -Math.random() * 320;
}
requestAnimationFrame(draw);
}
resize();
window.addEventListener("resize", resize, { passive: true });
draw();
return true;
}
// Gradio DOM bazen geç geliyor → retry
let tries = 0;
const t = setInterval(() => {
tries++;
if (init() || tries > 60) clearInterval(t);
}, 150);
})();
</script>
""")
gr.Markdown(HEADER_MD)
# Boot animasyonu (artık kaybolmuyor)
gr.HTML("""
<div class="pb-intro">
<div class="pb-intro-line">INITIALIZING BCE CORE...</div>
<div class="pb-intro-line">LOADING PERSONALITY MODULES...</div>
<div class="pb-intro-line">BOOT COMPLETE.</div>
</div>
""")
with gr.Row():
with gr.Column(scale=2, elem_id="prettybird-chat"):
chatbot = gr.ChatInterface(
fn=respond,
)
with gr.Column(scale=1):
gr.HTML(
'<div class="pb-side-card">'
'<h3>🕊️ BCE in a Nutshell</h3>'
f'<p>{BCE_SHORT_TR}</p>'
# === MINI BCE SPECS TABLE ===
'<div class="bce-mini-table">'
'<div class="bce-row"><span class="bce-key">Architecture</span><span class="bce-val">LLAMA-based</span></div>'
'<div class="bce-row"><span class="bce-key">Parameters</span><span class="bce-val">1B</span></div>'
'<div class="bce-row"><span class="bce-key">Quantization</span><span class="bce-val">FP16</span></div>'
'<div class="bce-row"><span class="bce-key">Context</span><span class="bce-val">4K</span></div>'
'<div class="bce-row"><span class="bce-key">BCE Version</span><span class="bce-val">v0.3.1</span></div>'
'</div>'
# === BCE METERS (aynı kaldı) ===
'<div class="bce-meter">'
'<div class="bce-meter-row">'
'<span class="bce-meter-label">BCE State</span>'
'<div class="bce-meter-bar"><div class="bce-meter-fill state"></div></div>'
'</div>'
'<div class="bce-meter-row">'
'<span class="bce-meter-label">Stability</span>'
'<div class="bce-meter-bar"><div class="bce-meter-fill stability"></div></div>'
'</div>'
'<div class="bce-meter-row">'
'<span class="bce-meter-label">Creativity</span>'
'<div class="bce-meter-bar"><div class="bce-meter-fill creativity"></div></div>'
'</div>'
'</div>'
'</div>'
)# Music
with gr.Group(elem_classes=["pb-music-wrap"]):
gr.HTML(
f"""
<div class="pb-music-title">
🎵 {MUSIC_TITLE}{MUSIC_ARTIST}
• <a href="{MUSIC_LINK}" target="_blank" rel="noopener">Source</a>
</div>
"""
)
music = gr.Audio(
value=MUSIC_FILE_REL, # relative path in repo
autoplay=True,
loop=True,
interactive=False,
show_label=False,
elem_classes=["pb-audio"]
)
if __name__ == "__main__":
demo.launch()