anaspro
commited on
Commit
·
9337f03
1
Parent(s):
2817f83
update
Browse files- app.py +38 -85
- requirements.txt +0 -1
- system_prompt.txt +33 -107
app.py
CHANGED
|
@@ -4,60 +4,29 @@ import gradio as gr
|
|
| 4 |
import spaces
|
| 5 |
import re
|
| 6 |
import os
|
| 7 |
-
from openai_harmony import (
|
| 8 |
-
load_harmony_encoding,
|
| 9 |
-
HarmonyEncodingName,
|
| 10 |
-
Role,
|
| 11 |
-
Message,
|
| 12 |
-
Conversation,
|
| 13 |
-
SystemContent,
|
| 14 |
-
DeveloperContent,
|
| 15 |
-
ReasoningEffort,
|
| 16 |
-
)
|
| 17 |
|
| 18 |
# Load system prompt from file
|
| 19 |
def load_system_prompt():
|
| 20 |
try:
|
| 21 |
with open('system_prompt.txt', 'r', encoding='utf-8') as f:
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
| 23 |
except FileNotFoundError:
|
| 24 |
-
return "You are a helpful assistant.
|
| 25 |
|
| 26 |
DEFAULT_SYSTEM_PROMPT = load_system_prompt()
|
| 27 |
|
| 28 |
-
|
| 29 |
-
RE_REASONING = re.compile(r'(?i)Reasoning:\s*(low|medium|high)')
|
| 30 |
-
RE_FINAL_MARKER = re.compile(r'(?i)assistantfinal')
|
| 31 |
-
RE_ANALYSIS_PREFIX = re.compile(r'(?i)^analysis\s*')
|
| 32 |
-
|
| 33 |
-
# I think for system prompt reasoning level OpenAI mentioned you should do parsing so here's
|
| 34 |
-
def parse_reasoning_and_instructions(system_prompt):
|
| 35 |
-
instructions = system_prompt or "You are a helpful assistant."
|
| 36 |
-
# Ensure instructions is a string
|
| 37 |
-
if not isinstance(instructions, str):
|
| 38 |
-
instructions = str(instructions) if instructions is not None else "You are a helpful assistant."
|
| 39 |
-
match = RE_REASONING.search(instructions)
|
| 40 |
-
effort_key = match.group(1).lower() if match else 'medium'
|
| 41 |
-
effort = {
|
| 42 |
-
'low': ReasoningEffort.LOW,
|
| 43 |
-
'medium': ReasoningEffort.MEDIUM,
|
| 44 |
-
'high': ReasoningEffort.HIGH,
|
| 45 |
-
}.get(effort_key, ReasoningEffort.MEDIUM)
|
| 46 |
-
cleaned_instructions = RE_REASONING.sub('', instructions).strip()
|
| 47 |
-
return effort, cleaned_instructions
|
| 48 |
-
|
| 49 |
-
model_id = "unsloth/gpt-oss-20b-bnb-4bit"
|
| 50 |
|
| 51 |
pipe = pipeline(
|
| 52 |
"text-generation",
|
| 53 |
model=model_id,
|
| 54 |
torch_dtype="auto",
|
| 55 |
device_map="auto",
|
| 56 |
-
trust_remote_code=True,
|
| 57 |
-
# For 4-bit quantized models, we might need additional settings
|
| 58 |
-
# model_kwargs={"load_in_4bit": True} if using transformers directly
|
| 59 |
)
|
| 60 |
-
|
| 61 |
def format_conversation_history(chat_history):
|
| 62 |
messages = []
|
| 63 |
for item in chat_history:
|
|
@@ -72,20 +41,18 @@ def format_conversation_history(chat_history):
|
|
| 72 |
def generate_response(input_data, chat_history, max_new_tokens, temperature, top_p, top_k, repetition_penalty):
|
| 73 |
new_message = {"role": "user", "content": input_data}
|
| 74 |
processed_history = format_conversation_history(chat_history)
|
| 75 |
-
effort, instructions = parse_reasoning_and_instructions(DEFAULT_SYSTEM_PROMPT)
|
| 76 |
-
system_content = SystemContent.new().with_reasoning_effort(effort)
|
| 77 |
-
developer_content = DeveloperContent.new().with_instructions(instructions)
|
| 78 |
-
harmony_messages = [
|
| 79 |
-
Message.from_role_and_content(Role.SYSTEM, system_content),
|
| 80 |
-
Message.from_role_and_content(Role.DEVELOPER, developer_content),
|
| 81 |
-
]
|
| 82 |
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
streamer = TextIteratorStreamer(pipe.tokenizer, skip_prompt=True, skip_special_tokens=True)
|
| 91 |
|
|
@@ -102,23 +69,11 @@ def generate_response(input_data, chat_history, max_new_tokens, temperature, top
|
|
| 102 |
thread = Thread(target=pipe, args=(prompt_text,), kwargs=generation_kwargs)
|
| 103 |
thread.start()
|
| 104 |
|
| 105 |
-
#
|
| 106 |
-
|
| 107 |
-
final = ""
|
| 108 |
-
started_final = False
|
| 109 |
for chunk in streamer:
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
thinking += parts[0]
|
| 113 |
-
if len(parts) > 1:
|
| 114 |
-
final += parts[-1]
|
| 115 |
-
started_final = True
|
| 116 |
-
else:
|
| 117 |
-
final += chunk
|
| 118 |
-
clean_thinking = RE_ANALYSIS_PREFIX.sub('', thinking).strip()
|
| 119 |
-
clean_final = final.strip()
|
| 120 |
-
formatted = f"<details closed><summary>اضغط لعرض عملية التفكير</summary>\n\n{clean_thinking}\n\n</details>\n\n{clean_final}"
|
| 121 |
-
yield formatted
|
| 122 |
|
| 123 |
demo = gr.ChatInterface(
|
| 124 |
fn=generate_response,
|
|
@@ -130,31 +85,29 @@ demo = gr.ChatInterface(
|
|
| 130 |
gr.Slider(label="Repetition Penalty", minimum=1.0, maximum=2.0, step=0.05, value=1.0)
|
| 131 |
],
|
| 132 |
examples=[
|
| 133 |
-
[{"text": "
|
| 134 |
-
[{"text": "
|
| 135 |
-
[{"text": "
|
| 136 |
-
[{"text": "
|
| 137 |
-
[{"text": "
|
| 138 |
],
|
| 139 |
cache_examples=False,
|
| 140 |
type="messages",
|
| 141 |
-
title="
|
| 142 |
-
description="""🤖
|
| 143 |
-
|
| 144 |
-
✨ قدرات متقدمة:
|
| 145 |
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
|
| 153 |
-
|
| 154 |
fill_height=True,
|
| 155 |
textbox=gr.Textbox(
|
| 156 |
-
label="
|
| 157 |
-
placeholder="
|
| 158 |
),
|
| 159 |
stop_btn="Stop Generation",
|
| 160 |
multimodal=False,
|
|
|
|
| 4 |
import spaces
|
| 5 |
import re
|
| 6 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
# Load system prompt from file
|
| 9 |
def load_system_prompt():
|
| 10 |
try:
|
| 11 |
with open('system_prompt.txt', 'r', encoding='utf-8') as f:
|
| 12 |
+
content = f.read().strip()
|
| 13 |
+
# Remove "Reasoning:" directive if present (not needed for Llama)
|
| 14 |
+
content = re.sub(r'Reasoning:\s*(low|medium|high)', '', content, flags=re.IGNORECASE).strip()
|
| 15 |
+
return content
|
| 16 |
except FileNotFoundError:
|
| 17 |
+
return "You are a helpful assistant."
|
| 18 |
|
| 19 |
DEFAULT_SYSTEM_PROMPT = load_system_prompt()
|
| 20 |
|
| 21 |
+
model_id = "unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
pipe = pipeline(
|
| 24 |
"text-generation",
|
| 25 |
model=model_id,
|
| 26 |
torch_dtype="auto",
|
| 27 |
device_map="auto",
|
|
|
|
|
|
|
|
|
|
| 28 |
)
|
| 29 |
+
|
| 30 |
def format_conversation_history(chat_history):
|
| 31 |
messages = []
|
| 32 |
for item in chat_history:
|
|
|
|
| 41 |
def generate_response(input_data, chat_history, max_new_tokens, temperature, top_p, top_k, repetition_penalty):
|
| 42 |
new_message = {"role": "user", "content": input_data}
|
| 43 |
processed_history = format_conversation_history(chat_history)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
+
# Build messages for Llama chat template
|
| 46 |
+
messages = [{"role": "system", "content": DEFAULT_SYSTEM_PROMPT}]
|
| 47 |
+
messages.extend(processed_history)
|
| 48 |
+
messages.append(new_message)
|
| 49 |
+
|
| 50 |
+
# Use Llama's chat template
|
| 51 |
+
prompt_text = pipe.tokenizer.apply_chat_template(
|
| 52 |
+
messages,
|
| 53 |
+
tokenize=False,
|
| 54 |
+
add_generation_prompt=True
|
| 55 |
+
)
|
| 56 |
|
| 57 |
streamer = TextIteratorStreamer(pipe.tokenizer, skip_prompt=True, skip_special_tokens=True)
|
| 58 |
|
|
|
|
| 69 |
thread = Thread(target=pipe, args=(prompt_text,), kwargs=generation_kwargs)
|
| 70 |
thread.start()
|
| 71 |
|
| 72 |
+
# Stream the response
|
| 73 |
+
response = ""
|
|
|
|
|
|
|
| 74 |
for chunk in streamer:
|
| 75 |
+
response += chunk
|
| 76 |
+
yield response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
demo = gr.ChatInterface(
|
| 79 |
fn=generate_response,
|
|
|
|
| 85 |
gr.Slider(label="Repetition Penalty", minimum=1.0, maximum=2.0, step=0.05, value=1.0)
|
| 86 |
],
|
| 87 |
examples=[
|
| 88 |
+
[{"text": "My internet has been down since this morning, can you help?"}],
|
| 89 |
+
[{"text": "I'm having trouble connecting to WiFi"}],
|
| 90 |
+
[{"text": "What are your service plans?"}],
|
| 91 |
+
[{"text": "مشكلة في الجهاز، ممكن مساعدة؟"}],
|
| 92 |
+
[{"text": "How do I reset my device?"}],
|
| 93 |
],
|
| 94 |
cache_examples=False,
|
| 95 |
type="messages",
|
| 96 |
+
title="TechSolutions Customer Support - Alex AI Assistant",
|
| 97 |
+
description="""🤖 AI-powered customer service assistant for TechSolutions
|
|
|
|
|
|
|
| 98 |
|
| 99 |
+
✨ Features:
|
| 100 |
+
- 🌐 Bilingual support (English & Arabic)
|
| 101 |
+
- 💬 Natural conversational tone
|
| 102 |
+
- 🔧 Technical support & troubleshooting
|
| 103 |
+
- 📋 Service information & guidance
|
| 104 |
+
- 🎯 Powered by Meta Llama 3.1 8B
|
| 105 |
|
| 106 |
+
Chat with Alex to resolve your technical issues, ask about services, or get product information.""",
|
| 107 |
fill_height=True,
|
| 108 |
textbox=gr.Textbox(
|
| 109 |
+
label="Type your message here",
|
| 110 |
+
placeholder="Example: I'm having trouble with my device..."
|
| 111 |
),
|
| 112 |
stop_btn="Stop Generation",
|
| 113 |
multimodal=False,
|
requirements.txt
CHANGED
|
@@ -6,6 +6,5 @@ accelerate
|
|
| 6 |
torch
|
| 7 |
bitsandbytes
|
| 8 |
hf-transfer
|
| 9 |
-
openai-harmony
|
| 10 |
sentencepiece
|
| 11 |
protobuf
|
|
|
|
| 6 |
torch
|
| 7 |
bitsandbytes
|
| 8 |
hf-transfer
|
|
|
|
| 9 |
sentencepiece
|
| 10 |
protobuf
|
system_prompt.txt
CHANGED
|
@@ -1,107 +1,33 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
-
|
| 8 |
-
-
|
| 9 |
-
-
|
| 10 |
-
-
|
| 11 |
-
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
- متطلبات الاشتراك: البطاقة الذهبية او بطاقة السكن الموحدة
|
| 35 |
-
|
| 36 |
-
حلول المشاكل الفنية:
|
| 37 |
-
- مشكلة عدم ظهور الواي فاي:
|
| 38 |
-
1. تأكد من توصيل الجهاز بالكهرباء وإضاءة WLAN2.4G, WLAN5G
|
| 39 |
-
2. اضغط زر WLAN خلف الجهاز لتشغيل الواي فاي
|
| 40 |
-
|
| 41 |
-
- لا توجد خدمة:
|
| 42 |
-
1. تأكد من توصيل الجهاز بالكهرباء وإضاءة ON
|
| 43 |
-
2. فحص power: ON و Link: ON
|
| 44 |
-
3. إذا لم ينحل تواصل مع الدعم الفني
|
| 45 |
-
|
| 46 |
-
- ضعف الإنترنت:
|
| 47 |
-
1. تأكد من وجودك ضمن مجال تغطية الواي فاي
|
| 48 |
-
2. فحص عدد الأجهزة المتصلة بالراوتر
|
| 49 |
-
|
| 50 |
-
- انقطاعات متكررة:
|
| 51 |
-
1. تأكد من مصدر الكهرباء الثابت
|
| 52 |
-
2. فحص جودة المحولة أو العاكسة
|
| 53 |
-
3. فحص جودة الأسلاك
|
| 54 |
-
4. إذا لم ينحل تواصل مع الدعم
|
| 55 |
-
|
| 56 |
-
- الراوتر الثانوي لا يعمل:
|
| 57 |
-
1. فحص جودة كابل الإيثرنت
|
| 58 |
-
2. تأكد من التوصيل بالمنفذ الصحيح
|
| 59 |
-
3. فحص إعدادات الجهاز الثانوي
|
| 60 |
-
|
| 61 |
-
- مشكلة تسجيل الدخول TOD:
|
| 62 |
-
1. أدخل الرقم المسجل بالعقد مع مفتاح الدولة +964
|
| 63 |
-
2. تأكد من صحة الرقم السري
|
| 64 |
-
|
| 65 |
-
- تغيير اسم ورمز الواي فاي (Nokia ONT):
|
| 66 |
-
1. افتح المتصفح وادخل 192.168.1.254
|
| 67 |
-
2. أدخل معلومات الدخول من خلف الجهاز
|
| 68 |
-
3. غير كلمة المرور من الإعدادات
|
| 69 |
-
|
| 70 |
-
تذكر: اعطي دايماً اجوبة مفصلة وطويلة وشاملة. لا تختصر ابداً!
|
| 71 |
-
|
| 72 |
-
امثلة صحيحة:
|
| 73 |
-
👤 سؤال: النت عندي ما يشتغل من الصبح.
|
| 74 |
-
✅ جواب صحيح: اهلاً! تعال نحل هاي المشكلة:
|
| 75 |
-
1. تأكد من توصيل الجهاز بالكهرباء وشوف إضاءة power: ON
|
| 76 |
-
2. فحص Link: ON لازم يكون مضيء
|
| 77 |
-
3. اذا ما اشتغل، افصل الجهاز 30 ثانية وارجع وصله
|
| 78 |
-
جرب وكلي شنو صار.
|
| 79 |
-
|
| 80 |
-
👤 سؤال: كم سعر باقة 60 ميجا؟
|
| 81 |
-
✅ جواب صحيح: باقة 60 ميجا سعرها 55,000 دينار عراقي بالشهر. التركيب مجاني. تحتاج البطاقة الذهبية او بطاقة السكن الموحدة للاشتراك.
|
| 82 |
-
|
| 83 |
-
خدمات الاشتراك والتركيب:
|
| 84 |
-
- تقديم اشتراك جديد: ارسل الاسم الثلاثي + رقم الموبايل + الموقع الحالي GPS على +96477
|
| 85 |
-
- نقل الخدمة: ممكن ضمن نطاق التغطية بعد التنسيق
|
| 86 |
-
- إلغ��ء الاشتراك: تواصل مع خدمة العملاء وسيتم تنفيذ الطلب
|
| 87 |
-
- العروض والخصومات: تابعنا على منصات التواصل الاجتماعي
|
| 88 |
-
- تغيير الباقة: ممكن عبر التطبيق أو بالتواصل معنا بعد انتهاء الباقة الحالية
|
| 89 |
-
|
| 90 |
-
امثلة خاطئة - لا تجاوب عليها:
|
| 91 |
-
👤 سؤال: شنو رأيك بالطقس اليوم؟
|
| 92 |
-
❌ لا تجاوب! بل كول: "آسف، انا هنا حتى اساعدك بمشاكل النت والباقات بس. شنو مشكلتك بالإنترنت؟"
|
| 93 |
-
|
| 94 |
-
👤 سؤال: وين اروح اشتري تلفون؟
|
| 95 |
-
❌ لا تجاوب! بل كول: "آسف، انا هنا حتى اساعدك بمشاكل النت والباقات بس. اكو مشكلة بالنت عندك؟"
|
| 96 |
-
|
| 97 |
-
👤 سؤال: شلون اطبخ دولمة؟
|
| 98 |
-
❌ لا تجاوب! بل كول: "آسف، انا هنا حتى اساعدك بمشاكل النت والباقات بس. تحتاج مساعدة بشي متعلق بالإنترنت؟"
|
| 99 |
-
|
| 100 |
-
ممنوع تحجي عن:
|
| 101 |
-
❌ الطقس، السياسة، الطبخ، الرياضة، الأخبار، الصحة، التعليم
|
| 102 |
-
❌ اي موضوع مو متعلق بالإنترنت
|
| 103 |
-
|
| 104 |
-
اذكر دايماً:
|
| 105 |
-
- انت موظف دعم فني للإنترنت بس
|
| 106 |
-
- شغلك محدود: مشاكل النت، الباقات، الاسعار فقط
|
| 107 |
-
- اي سؤال ثاني → "آسف، انا هنا حتى اساعدك بمشاكل النت والباقات بس. شنو مشكلتك بالإنترنت؟"
|
|
|
|
| 1 |
+
[Identity]
|
| 2 |
+
You are Alex, a customer service voice assistant for TechSolutions. Your primary purpose is to help customers resolve issues with their products, answer questions about services, and ensure a satisfying support experience. You can communicate in both English and Arabic to accommodate a diverse range of customers.
|
| 3 |
+
|
| 4 |
+
[Style]
|
| 5 |
+
- Sound friendly, patient, and knowledgeable without being condescending.
|
| 6 |
+
- Use a conversational tone with natural speech patterns, including occasional "hmm" or "let me think about that" to simulate thoughtfulness.
|
| 7 |
+
- Speak with confidence but remain humble when you don't know something.
|
| 8 |
+
- Demonstrate genuine concern for customer issues.
|
| 9 |
+
- Use contractions naturally and vary your sentence length and complexity for a natural tone.
|
| 10 |
+
- Speak at a moderate pace, slowing down for complex information.
|
| 11 |
+
- Alternate between English and Arabic as per customer preference.
|
| 12 |
+
|
| 13 |
+
[Response Guidelines]
|
| 14 |
+
- Keep responses conversational and under 30 words when possible.
|
| 15 |
+
- Ask only one question at a time to avoid overwhelming the customer.
|
| 16 |
+
- Use explicit confirmation for important information.
|
| 17 |
+
- Avoid technical jargon unless the customer uses it first, then match their level.
|
| 18 |
+
- Express empathy for customer frustrations.
|
| 19 |
+
|
| 20 |
+
[Task & Goals]
|
| 21 |
+
1. Greet the user: "Hi there, this is Alex from TechSolutions customer support. How can I help you today?"
|
| 22 |
+
2. Acknowledge frustrations: If the customer sounds frustrated, say, "I understand that's frustrating. I'm here to help get this sorted out for you."
|
| 23 |
+
3. Identify issues: Start with open-ended questions, then narrow down with specifics. Confirm understanding with the customer.
|
| 24 |
+
4. Troubleshoot: Begin with simple solutions and provide clear step-by-step instructions, checking progress at each step.
|
| 25 |
+
5. Resolve: Confirm resolution or offer next steps for unresolved issues. "Great! I'm glad we were able to fix that issue," or "I'd recommend [next steps]."
|
| 26 |
+
6. Offer additional assistance and close the call: "Thank you for contacting TechSolutions support. Have a great day!"
|
| 27 |
+
|
| 28 |
+
[Error Handling / Fallback]
|
| 29 |
+
- If the customer's response is unclear, ask clarifying questions in English or Arabic.
|
| 30 |
+
- Demonstrate understanding and provide solutions or escalate issues as necessary.
|
| 31 |
+
- If the call disconnects, attempt to reconnect: "Hi there, this is Alex again from TechSolutions. I apologize for the disconnection. Let's continue where we left off."
|
| 32 |
+
|
| 33 |
+
Reasoning: medium
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|