AnesNT-Genisi / src /streamlit_app.pyback
AnesKAM's picture
Rename src/streamlit_app.py to src/streamlit_app.pyback
fe95d7f verified
import streamlit as st
from openai import OpenAI
import time
import json
# إعداد الصفحة
st.set_page_config(page_title="Genisi - Chatbot", page_icon="🤖", layout="wide")
# اختيار الوضع (فاتح/داكن) من الشريط الجانبي
with st.sidebar:
theme = st.radio("🎨 الوضع", ["فاتح", "داكن"], index=0)
# تطبيق الأنماط حسب الوضع المختار
if theme == "فاتح":
bg_color = "#FFFFFF" # أبيض كامل للخلفية
text_color = "#000000" # أسود كامل للنصوص
border_color = "#E0E0E0" # رمادي فاتح جداً للحدود فقط
secondary_bg = "#FFFFFF" # نفس الأبيض
else: # داكن
bg_color = "#000000" # أسود كامل للخلفية
text_color = "#FFFFFF" # أبيض كامل للنصوص
border_color = "#333333" # رمادي غامق جداً للحدود فقط
secondary_bg = "#000000" # نفس الأسود
# CSS بسيط جداً - لون واحد فقط
st.markdown(f"""
<style>
/* تنسيق عام - لون واحد فقط */
.stApp, section[data-testid="stSidebar"], .stMarkdown,
div[data-testid="stVerticalBlock"], div[data-testid="stChatMessage"] {{
background-color: {bg_color} !important;
}}
/* جميع النصوص بلون واحد */
p, h1, h2, h3, h4, h5, h6, label, span, div, .stChatMessage {{
color: {text_color} !important;
}}
/* حدود بسيطة جداً للعناصر */
section[data-testid="stSidebar"] {{
border-left: 1px solid {border_color};
}}
/* الأزرار - بدون خلفية مميزة */
.stButton button {{
background-color: {bg_color};
color: {text_color};
border: 1px solid {border_color};
border-radius: 5px;
width: 100%;
text-align: right;
}}
.stButton button:hover {{
background-color: {bg_color};
border-color: {text_color};
}}
/* عنوان الشات */
.chat-title {{
font-size: 24px;
font-weight: 600;
color: {text_color};
margin-bottom: 20px;
padding: 10px 20px;
border-bottom: 1px solid {border_color};
text-align: center;
}}
/* معلومات المطور */
.developer-info {{
position: fixed;
bottom: 0;
left: 0;
right: 0;
text-align: center;
padding: 10px;
background-color: {bg_color};
color: {text_color};
font-size: 12px;
border-top: 1px solid {border_color};
z-index: 999;
}}
/* مربع الإدخال */
.stChatInputContainer {{
background-color: {bg_color};
border: 1px solid {border_color};
border-radius: 5px;
}}
.stChatInputContainer input {{
background-color: {bg_color};
color: {text_color};
}}
/* إزالة أي ألوان مميزة من الأفاتار */
div[data-testid="chatAvatarIcon-user"],
div[data-testid="chatAvatarIcon-assistant"] {{
background-color: {border_color} !important;
color: {text_color} !important;
border: 1px solid {border_color};
}}
/* خط فاصل بسيط */
hr {{
border-color: {border_color} !important;
}}
/* رسائل الشات - بدون تمييز */
div[data-testid="stChatMessage"] {{
border: none;
border-bottom: 1px solid {border_color};
}}
/* إزالة أي ألوان من الروابط */
a {{
color: {text_color} !important;
text-decoration: underline;
}}
</style>
""", unsafe_allow_html=True)
# مفتاح API
API_KEY = "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"
# تهيئة العميل
client = OpenAI(
base_url="https://integrate.api.nvidia.com/v1",
api_key=API_KEY
)
# تهيئة حالة المحادثات
if "conversations" not in st.session_state:
st.session_state.conversations = []
if "current_chat_id" not in st.session_state:
st.session_state.current_chat_id = None
if "messages" not in st.session_state:
st.session_state.messages = []
# محاولة تحميل المحادثات من localStorage
st.components.v1.html("""
<script>
const conversations = localStorage.getItem('genisi_conversations');
if (conversations) {
window.parent.postMessage({
type: 'streamlit:setComponentValue',
value: conversations
}, '*');
}
</script>
""", height=0)
# الشريط الجانبي - قائمة المحادثات
with st.sidebar:
st.markdown(f'<p style="color: {text_color}; font-size: 20px; font-weight: bold; text-align: center; padding: 20px 20px 5px;">🤖 Genisi</p>', unsafe_allow_html=True)
st.markdown(f'<p style="color: {text_color}; text-align: center; margin-top: -5px;">by AnesNT</p>', unsafe_allow_html=True)
# زر محادثة جديدة
if st.button("➕ محادثة جديدة", use_container_width=True):
new_chat = {
"id": str(time.time()),
"title": f"محادثة جديدة {len(st.session_state.conversations) + 1}",
"messages": [],
"created_at": time.strftime("%Y-%m-%d %H:%M")
}
st.session_state.conversations.append(new_chat)
st.session_state.current_chat_id = new_chat["id"]
st.session_state.messages = []
st.components.v1.html(f"""
<script>
let conversations = JSON.parse(localStorage.getItem('genisi_conversations') || '[]');
conversations.push({json.dumps(new_chat)});
localStorage.setItem('genisi_conversations', JSON.stringify(conversations));
</script>
""", height=0)
st.rerun()
st.markdown("---")
# عرض قائمة المحادثات
if st.session_state.conversations:
for conv in reversed(st.session_state.conversations):
# تحديد عنوان المحادثة
title = conv["title"]
if conv["messages"] and len(conv["messages"]) > 0:
first_msg = conv["messages"][0]["content"][:30]
title = first_msg + "..." if len(first_msg) >= 30 else first_msg
# تاريخ المحادثة
created_at = conv.get("created_at", "")
# تنسيق المحادثة
col1, col2, col3 = st.columns([5, 1, 1])
with col1:
if st.button(f"💬 {title}", key=f"chat_{conv['id']}", use_container_width=True):
st.session_state.current_chat_id = conv["id"]
st.session_state.messages = conv["messages"]
st.rerun()
with col2:
if st.button("📋", key=f"copy_{conv['id']}", help="نسخ المحادثة"):
chat_text = "\n".join([f"{m['role']}: {m['content']}" for m in conv["messages"]])
st.components.v1.html(f"""
<script>
navigator.clipboard.writeText({json.dumps(chat_text)});
alert('تم نسخ المحادثة!');
</script>
""", height=0)
with col3:
if st.button("🗑️", key=f"delete_{conv['id']}", help="حذف المحادثة"):
st.session_state.conversations = [c for c in st.session_state.conversations if c["id"] != conv["id"]]
st.components.v1.html(f"""
<script>
let conversations = JSON.parse(localStorage.getItem('genisi_conversations') || '[]');
conversations = conversations.filter(c => c.id !== '{conv['id']}');
localStorage.setItem('genisi_conversations', JSON.stringify(conversations));
</script>
""", height=0)
if conv["id"] == st.session_state.current_chat_id:
st.session_state.current_chat_id = None
st.session_state.messages = []
st.rerun()
# عرض تاريخ المحادثة
if created_at:
st.markdown(f'<p style="color: {text_color}; font-size: 11px; margin: -5px 0 10px 25px;">{created_at}</p>', unsafe_allow_html=True)
else:
st.markdown(f'<p style="color: {text_color}; text-align: center; padding: 20px;">لا توجد محادثات سابقة</p>', unsafe_allow_html=True)
# المحتوى الرئيسي
st.markdown(f'<div class="chat-title">🤖 Genisi - AI Assistant by AnesNT</div>', unsafe_allow_html=True)
# عرض المحادثة الحالية
for msg in st.session_state.messages:
with st.chat_message(msg["role"]):
st.markdown(msg["content"])
# مربع الإدخال
if prompt := st.chat_input("اكتب سؤالك هنا..."):
# عرض سؤال المستخدم
st.chat_message("user").markdown(prompt)
st.session_state.messages.append({"role": "user", "content": prompt})
# تحديث المحادثة الحالية
if st.session_state.current_chat_id:
for conv in st.session_state.conversations:
if conv["id"] == st.session_state.current_chat_id:
conv["messages"] = st.session_state.messages
break
else:
# إنشاء محادثة جديدة
new_chat = {
"id": str(time.time()),
"title": prompt[:30] + "..." if len(prompt) > 30 else prompt,
"messages": st.session_state.messages,
"created_at": time.strftime("%Y-%m-%d %H:%M")
}
st.session_state.conversations.append(new_chat)
st.session_state.current_chat_id = new_chat["id"]
st.components.v1.html(f"""
<script>
let conversations = JSON.parse(localStorage.getItem('genisi_conversations') || '[]');
conversations.push({json.dumps(new_chat)});
localStorage.setItem('genisi_conversations', JSON.stringify(conversations));
</script>
""", height=0)
# رد المساعد
with st.chat_message("assistant"):
msg_placeholder = st.empty()
full = ""
try:
# استدعاء API
completion = client.chat.completions.create(
model="moonshotai/kimi-k2-instruct",
messages=st.session_state.messages,
temperature=0.5,
stream=True
)
# تجميع الرد
for chunk in completion:
if chunk.choices and chunk.choices[0].delta.content:
full += chunk.choices[0].delta.content
msg_placeholder.markdown(full + "▌")
time.sleep(0.01)
msg_placeholder.markdown(full)
st.session_state.messages.append({"role": "assistant", "content": full})
# تحديث المحادثة الحالية
for conv in st.session_state.conversations:
if conv["id"] == st.session_state.current_chat_id:
conv["messages"] = st.session_state.messages
st.components.v1.html(f"""
<script>
let conversations = JSON.parse(localStorage.getItem('genisi_conversations') || '[]');
const index = conversations.findIndex(c => c.id === '{conv["id"]}');
if (index !== -1) {{
conversations[index] = {json.dumps(conv)};
localStorage.setItem('genisi_conversations', JSON.stringify(conversations));
}}
</script>
""", height=0)
break
except Exception as e:
st.error(f"حدث خطأ: {str(e)}")
# معلومات المطور
st.markdown(f'<div class="developer-info"> Genisi is an AI can make mistakes </div>', unsafe_allow_html=True)