import gradio as gr
Browse filesimport requests
# Endpoints ثابتة
AZURE_CHAT_ENDPOINT = "https://lahja-dev-resource.cognitiveservices.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2025-01-01-preview"
AZURE_TTS_ENDPOINT = "https://lahja-dev-resource.cognitiveservices.azure.com/openai/deployments/LAHJA-V1/audio/speech?api-version=2025-03-01-preview"
# --- GPT رد ---
def chat_with_gpt(text, api_key):
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
# system prompt لتعريف الشخصية
messages = [
{
"role": "system",
"content": (
"انت مساعد ذكي اسمه (لهجة)، مطور من قبل شركة (أسس الذكاء الرقمي). "
"رد دايمًا باللهجة النجدية السعودية. "
"خلك مختصر وواضح."
)
},
{"role": "user", "content": text}
]
data = {
"messages": messages,
"max_tokens": 512,
"temperature": 0.8,
"top_p": 1,
"model": "gpt-4o"
}
response = requests.post(AZURE_CHAT_ENDPOINT, json=data, headers=headers)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
return f"Error: {response.status_code}\n{response.text}"
# --- تحويل نص لصوت ---
def text_to_speech(text, voice, speed, filename, api_key):
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
data = {
"model": "LAHJA-V1",
"input": text,
"voice": voice,
"speed": speed
}
response = requests.post(AZURE_TTS_ENDPOINT, json=data, headers=headers)
if response.status_code == 200:
with open(filename, "wb") as f:
f.write(response.content)
return filename
else:
return None
# --- دالة رئيسية ---
def chat_and_speak(user_input, voice, speed, history, api_key):
reply = chat_with_gpt(user_input, api_key)
# صوت السؤال
q_audio = text_to_speech(user_input, voice, speed, "question.wav", api_key)
# صوت الجواب
a_audio = text_to_speech(reply, voice, speed, "answer.wav", api_key)
# تحديث المحادثة
history = history + [(user_input, reply)]
return history, q_audio, a_audio
# --- التحقق من مفتاح الدخول ---
def check_key(user_key):
if user_key.strip() == "":
return gr.update(visible=True), gr.update(visible=False), None
else:
return gr.update(visible=False), gr.update(visible=True), user_key
# --- واجهة Gradio ---
with gr.Blocks(theme=gr.themes.Soft(), title="لهجة AI") as demo:
# -------- صفحة تسجيل الدخول --------
with gr.Group(visible=True) as login_page:
gr.Markdown(
"""
<div style="text-align:center; padding: 40px;">
<h1 style="color:#8B0000; font-size: 40px;">🔐 دخول إلى لهجة AI</h1>
<p style="font-size:18px; color:#444;">من فضلك أدخل مفتاح API للوصول إلى النظام</p>
</div>
""",
)
key_box = gr.Textbox(
placeholder="ادخل كود الدخول (API KEY)...",
label="API Key",
type="password"
)
login_btn = gr.Button("🚀 دخول", elem_id="login_btn")
api_key_state = gr.State()
# -------- صفحة المحادثة --------
with gr.Group(visible=False) as chat_page:
gr.Markdown(
"""
<div style="text-align:center; padding: 10px;">
<h1 style="color:#8B0000; font-size: 38px;">🤖 لهجة AI</h1>
<p style="font-size:18px; color:#333;">مطور من قبل شركة أسس الذكاء الرقمي | مساعد ذكي باللهجة النجدية</p>
</div>
"""
)
with gr.Row():
# عمود المحادثة
with gr.Column(scale=2):
chatbot = gr.Chatbot(label="المحادثة", height=450, bubble_full_width=False)
user_input = gr.Textbox(
placeholder="💬 اكتب سؤالك هنا...",
label="📌 نص المستخدم"
)
with gr.Row():
voice = gr.Dropdown(choices=["alloy"], value="alloy", label="🎙️ اختر الصوت")
speed = gr.Slider(minimum=0.5, maximum=2.0, value=1.0, step=0.1, label="⚡ سرعة الكلام")
send_btn = gr.Button("📤 أرسل", elem_classes="send-btn")
# عمود الصوت
with gr.Column(scale=1):
gr.Markdown("### 🔊 المخرجات الصوتية")
q_audio = gr.Audio(type="filepath", label="صوت السؤال")
a_audio = gr.Audio(type="filepath", label="صوت الجواب")
state = gr.State([])
send_btn.click(
fn=chat_and_speak,
inputs=[user_input, voice, speed, state, api_key_state],
outputs=[chatbot, q_audio, a_audio],
)
# -------- تحكم بظهور الصفحات --------
login_btn.click(
fn=check_key,
inputs=[key_box],
outputs=[login_page, chat_page, api_key_state],
)
demo.launch()
|
@@ -78,8 +78,11 @@
|
|
| 78 |
<div class="flex items-center">
|
| 79 |
<label for="voiceSelect" class="ml-2 text-sm font-medium text-gray-700">الصوت:</label>
|
| 80 |
<select id="voiceSelect" class="border border-gray-300 rounded-md px-3 py-1 text-sm focus:ring-red-600 focus:border-red-600 outline-none">
|
| 81 |
-
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
| 83 |
</div>
|
| 84 |
<div class="flex items-center">
|
| 85 |
<label for="speedSelect" class="ml-2 text-sm font-medium text-gray-700">السرعة:</label>
|
|
@@ -101,8 +104,8 @@
|
|
| 101 |
</div>
|
| 102 |
|
| 103 |
<!-- Audio Players -->
|
| 104 |
-
<div id="audioSection" class="
|
| 105 |
-
|
| 106 |
<h3 class="font-medium text-gray-800 mb-2">صوت السؤال</h3>
|
| 107 |
<audio id="questionAudio" controls class="w-full"></audio>
|
| 108 |
</div>
|
|
@@ -123,9 +126,9 @@
|
|
| 123 |
</div>
|
| 124 |
</footer>
|
| 125 |
</div>
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
const chatContainer = document.getElementById('chatContainer');
|
| 130 |
const userInput = document.getElementById('userInput');
|
| 131 |
const sendBtn = document.getElementById('sendBtn');
|
|
@@ -134,6 +137,8 @@
|
|
| 134 |
const questionAudio = document.getElementById('questionAudio');
|
| 135 |
const answerAudio = document.getElementById('answerAudio');
|
| 136 |
const audioSection = document.getElementById('audioSection');
|
|
|
|
|
|
|
| 137 |
|
| 138 |
// Add message to chat
|
| 139 |
function addMessage(text, isUser) {
|
|
@@ -168,26 +173,44 @@
|
|
| 168 |
chatContainer.appendChild(loadingDiv);
|
| 169 |
chatContainer.scrollTop = chatContainer.scrollHeight;
|
| 170 |
|
| 171 |
-
|
| 172 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
// Remove loading
|
| 174 |
chatContainer.removeChild(loadingDiv);
|
| 175 |
|
| 176 |
-
// Add bot response
|
| 177 |
-
const
|
| 178 |
-
|
| 179 |
-
"الله يسعدك، كل شي تمام الحين.",
|
| 180 |
-
"ياهلا والله، وش الجديد عندك؟",
|
| 181 |
-
"الحمدلله على كل حال، عندي اخبار حلوة اليوم."
|
| 182 |
-
];
|
| 183 |
-
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
|
| 184 |
-
addMessage(randomResponse, false);
|
| 185 |
|
| 186 |
-
// Show audio players
|
| 187 |
-
questionAudio.src =
|
| 188 |
-
answerAudio.src =
|
| 189 |
audioSection.classList.remove('hidden');
|
| 190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
});
|
| 192 |
|
| 193 |
// Allow sending with Enter key
|
|
|
|
| 78 |
<div class="flex items-center">
|
| 79 |
<label for="voiceSelect" class="ml-2 text-sm font-medium text-gray-700">الصوت:</label>
|
| 80 |
<select id="voiceSelect" class="border border-gray-300 rounded-md px-3 py-1 text-sm focus:ring-red-600 focus:border-red-600 outline-none">
|
| 81 |
+
<option value="alloy">عادي</option>
|
| 82 |
+
<option value="echo">صدى</option>
|
| 83 |
+
<option value="nova">نوفا</option>
|
| 84 |
+
<option value="shimmer">شيمر</option>
|
| 85 |
+
</select>
|
| 86 |
</div>
|
| 87 |
<div class="flex items-center">
|
| 88 |
<label for="speedSelect" class="ml-2 text-sm font-medium text-gray-700">السرعة:</label>
|
|
|
|
| 104 |
</div>
|
| 105 |
|
| 106 |
<!-- Audio Players -->
|
| 107 |
+
<div id="audioSection" class="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
|
| 108 |
+
<div class="audio-player p-4 rounded-xl">
|
| 109 |
<h3 class="font-medium text-gray-800 mb-2">صوت السؤال</h3>
|
| 110 |
<audio id="questionAudio" controls class="w-full"></audio>
|
| 111 |
</div>
|
|
|
|
| 126 |
</div>
|
| 127 |
</footer>
|
| 128 |
</div>
|
| 129 |
+
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
| 130 |
+
<script>
|
| 131 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 132 |
const chatContainer = document.getElementById('chatContainer');
|
| 133 |
const userInput = document.getElementById('userInput');
|
| 134 |
const sendBtn = document.getElementById('sendBtn');
|
|
|
|
| 137 |
const questionAudio = document.getElementById('questionAudio');
|
| 138 |
const answerAudio = document.getElementById('answerAudio');
|
| 139 |
const audioSection = document.getElementById('audioSection');
|
| 140 |
+
const API_ENDPOINT = "https://your-gradio-app-url.com/api/predict"; // Replace with your Gradio API endpoint
|
| 141 |
+
const API_KEY = "YOUR_API_KEY_HERE"; // Replace with your actual API key
|
| 142 |
|
| 143 |
// Add message to chat
|
| 144 |
function addMessage(text, isUser) {
|
|
|
|
| 173 |
chatContainer.appendChild(loadingDiv);
|
| 174 |
chatContainer.scrollTop = chatContainer.scrollHeight;
|
| 175 |
|
| 176 |
+
try {
|
| 177 |
+
// Call GPT API
|
| 178 |
+
const response = await fetch("https://your-gradio-app-url.com/api/predict", {
|
| 179 |
+
method: "POST",
|
| 180 |
+
headers: {
|
| 181 |
+
"Content-Type": "application/json",
|
| 182 |
+
},
|
| 183 |
+
body: JSON.stringify({
|
| 184 |
+
data: [
|
| 185 |
+
message, // user_input
|
| 186 |
+
voiceSelect.value, // voice
|
| 187 |
+
parseFloat(speedSelect.value), // speed
|
| 188 |
+
[], // history
|
| 189 |
+
API_KEY // api_key
|
| 190 |
+
]
|
| 191 |
+
})
|
| 192 |
+
});
|
| 193 |
+
|
| 194 |
+
const result = await response.json();
|
| 195 |
+
const [history, q_audio, a_audio] = result.data;
|
| 196 |
+
|
| 197 |
// Remove loading
|
| 198 |
chatContainer.removeChild(loadingDiv);
|
| 199 |
|
| 200 |
+
// Add bot response
|
| 201 |
+
const reply = history[history.length-1][1];
|
| 202 |
+
addMessage(reply, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
|
| 204 |
+
// Show audio players
|
| 205 |
+
questionAudio.src = q_audio;
|
| 206 |
+
answerAudio.src = a_audio;
|
| 207 |
audioSection.classList.remove('hidden');
|
| 208 |
+
|
| 209 |
+
} catch (error) {
|
| 210 |
+
console.error("Error:", error);
|
| 211 |
+
chatContainer.removeChild(loadingDiv);
|
| 212 |
+
addMessage("حدث خطأ أثناء محاولة الاتصال بالخادم. الرجاء المحاولة لاحقاً.", false);
|
| 213 |
+
}
|
| 214 |
});
|
| 215 |
|
| 216 |
// Allow sending with Enter key
|