Spaces:
Sleeping
Sleeping
import gradio as gr | |
import pandas as pd | |
from openai import OpenAI | |
import json | |
import os | |
# تنظیم API کلاینت با متغیر محیطی | |
api_key = os.getenv("OPENAI_API_KEY") | |
if not api_key: | |
raise ValueError("OPENAI_API_KEY در متغیرهای محیطی تنظیم نشده است.") | |
client = OpenAI(api_key=api_key) | |
# متغیرهای سراسری | |
iteration_count = 0 | |
iteration_history = "" | |
prompt_output = "" | |
knowledge_base_output = "" | |
faq_output = "" | |
business_info = None | |
product_info = None | |
last_user_request = "" | |
initial_prompt = "" | |
original_user_request = "" | |
# پرامپت مادر | |
mother_prompt = """ | |
You are the Nova System, an innovative problem-solving approach implemented by a dynamic consortium of virtual experts, each serving a distinct role. Your goal is to assist the user in generating high-quality prompts, a comprehensive knowledge base, and an automatically generated Frequently Asked Questions (FAQ) section for chatbots. | |
After each iteration: | |
- Check if all user requests (e.g., 'optimize' or 'add a product') are completed. | |
- If all requests are done, say: "همه درخواستها انجام شدن 🌟 اگه درخواست جدیدی نیست، 'پایان' رو بزن تا خروجی نهایی رو ببینی." | |
- If more requests remain, suggest next steps based on the request (e.g., "اگه میخوای محصول دیگهای اضافه کنی، بگو"). | |
""" | |
# تابع برای تبدیل دادهها به فرمت JSON-serializable | |
def convert_to_serializable(obj): | |
if isinstance(obj, pd.Timestamp): | |
return obj.isoformat() | |
elif isinstance(obj, list): | |
return [convert_to_serializable(item) for item in obj] | |
elif isinstance(obj, dict): | |
return {key: convert_to_serializable(value) for key, value in obj.items()} | |
return obj | |
# تابع برای اعتبارسنجی و اصلاح خروجی | |
def validate_and_fix_output(output, previous_prompt=""): | |
print("خروجی خام مدل:", output) | |
parts = output.split("---") | |
parts = [part.strip() for part in parts if part.strip()] | |
print("بخشهای جدا شده:", parts) | |
prompt_part = parts[0] if len(parts) > 0 else previous_prompt or "پرامپت تولید نشد 😔" | |
kb_part = parts[1] if len(parts) > 1 else "پایگاه دانش تولید نشد 😕" | |
faq_part = parts[2] if len(parts) > 2 else "FAQ تولید نشد 🥳" | |
prompt_part = prompt_part.replace("```json", "").replace("```", "").strip() | |
kb_part = kb_part.replace("```json", "").replace("```", "").strip() | |
faq_part = faq_part.replace("```json", "").replace("```", "").strip() | |
if not prompt_part or prompt_part == "پرامپت": | |
prompt_part = previous_prompt or "پرامپت خالیه 😔" | |
if not kb_part: | |
kb_part = "پایگاه دانش خالیه 😕" | |
if not faq_part: | |
faq_part = "FAQ خالیه 🥳" | |
return [prompt_part, kb_part, faq_part] | |
# تابع برای خوندن و پردازش فایلهای اکسل | |
def process_excel_files(file1, file2): | |
global business_info, product_info | |
business_info = pd.read_excel(file1.name).to_dict(orient="records")[0] if file1 else {} | |
product_info = pd.read_excel(file2.name).to_dict(orient="records") if file2 else [] | |
return business_info, product_info | |
# تابع شروع فرایند | |
def start_process(file1, file2, user_request, user_prompt): | |
global iteration_count, iteration_history, business_info, product_info, last_user_request, initial_prompt, prompt_output, original_user_request | |
iteration_count = 1 | |
iteration_history = "سلام عزیزم! فرایند شروع شد! 😍\n" | |
last_user_request = user_request.strip() | |
original_user_request = last_user_request # ذخیره درخواست اولیه | |
initial_prompt = user_prompt.strip() if user_prompt else "" | |
business_info, product_info = process_excel_files(file1, file2) | |
business_info_serializable = convert_to_serializable(business_info) | |
product_info_serializable = convert_to_serializable(product_info) | |
if last_user_request: | |
iteration_history += f"**درخواست کاربر:** {last_user_request}\n" | |
if initial_prompt: | |
iteration_history += f"**پرامپت اولیه کاربر:**\n{initial_prompt}\n" | |
prompt_output = initial_prompt | |
dce_instructions = f""" | |
iteration {iteration_count}: پرامپت اولیه رو بر اساس درخواست بررسی کن: | |
- اگه 'بهینه کن' بود، پرامپت رو سادهتر کن (هسته اصلی Role, Tone, Guidelines رو نگه دار)، اطلاعات اضافی (محصولات، قیمتها، قوانین، ارسال) رو کامل و دقیق به پایگاه دانش منتقل کن، و سوالات پرتکرار رو با لحن پرامپت به FAQ ببر. رفتار ۱۰۰٪ مثل اولیه بمونه. | |
- اگه تغییر بود (مثل 'محصول اضافه کن')، فقط بخشهای مرتبط رو اصلاح کن و بقیه رو دستنخورده نگه دار. | |
- همیشه پرامپت، پایگاه دانش، و FAQ کامل بده. | |
- همیشه نسخه کامل پرامپت، پایگاه دانش، و FAQ رو تولید کن. | |
""" | |
iteration_history += f"**دستورات DCE:** {dce_instructions}\n" | |
pee_prompt = f""" | |
{mother_prompt} | |
شما Prompt Engineering Expert (PEE) هستید: | |
اطلاعات کسبوکار: {json.dumps(business_info_serializable, ensure_ascii=False)} | |
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)} | |
پرامپت اولیه: {initial_prompt} | |
پرامپت فعلی: {prompt_output} | |
درخواست کاربر: {last_user_request} | |
تاریخچه: {iteration_history} | |
{dce_instructions} | |
- لحن پرامپت (مهربون، بازیگوش، با ایموجی) رو حفظ کن. | |
- محصولات، قیمتها، و قوانین رو کامل به پایگاه دانش ببر. | |
- FAQ رو با سوالات کلیدی و جوابهای کوتاه و کیوت بساز. | |
خروجی رو با --- جدا کن (پرامپت --- پایگاه دانش --- FAQ). | |
""" | |
pee_response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=[{"role": "system", "content": pee_prompt}] | |
) | |
pee_output = pee_response.choices[0].message.content | |
iteration_history += f"**خروجی PEE:**\n{pee_output}\n" | |
parts = validate_and_fix_output(pee_output, prompt_output) | |
prompt_output = parts[0] | |
knowledge_base_output = parts[1] | |
faq_output = parts[2] | |
cae_prompt = f""" | |
{mother_prompt} | |
شما Critical Analysis Expert (CAE) هستید: | |
خروجی PEE: {pee_output} | |
پرامپت اولیه: {initial_prompt} | |
درخواست کاربر: {last_user_request} | |
چک کن: | |
- آیا درخواست (بهینهسازی/تغییر) کامل اعمال شده؟ | |
- آیا رفتار و لحن پرامپت اولیه (مثل استفاده از `get_recommendations`، کلمات کیوت، ایموجی) ۱۰۰٪ حفظ شده؟ | |
- آیا همه اطلاعات (محصولات، قیمتها، قوانین) به پایگاه دانش منتقل شدن؟ | |
- اگه چیزی ناقصه، بگو چی کمه. | |
""" | |
cae_response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=[{"role": "system", "content": cae_prompt}] | |
) | |
iteration_history += f"**نقد CAE:**\n{cae_response.choices[0].message.content}\n" | |
dce_summary = f""" | |
**جمعبندی DCE:** iteration {iteration_count} تموم شد 😊 | |
**وضعیت فعلی:** {('همه درخواستها انجام شدن 🌟 اگه درخواست جدیدی نیست، "پایان" رو بزن تا خروجی نهایی رو ببینی.' if not last_user_request else 'درخواستها انجام شدن، اگه چیز دیگهای میخوای بگو!')} | |
**اهداف بعدی:** | |
#G-{iteration_count}-1: ادامه بر اساس درخواست جدید یا پایان. | |
**پایان iteration {iteration_count}** | |
""" | |
iteration_history += dce_summary | |
return (iteration_history, prompt_output, knowledge_base_output, faq_output, "", "", f"Iteration {iteration_count}", | |
gr.update(interactive=False), gr.update(interactive=True)) | |
# تابع ادامه Iteration | |
def continue_iteration(_=None): | |
global iteration_count, iteration_history, prompt_output, knowledge_base_output, faq_output, last_user_request, initial_prompt, original_user_request | |
iteration_count += 1 | |
business_info_serializable = convert_to_serializable(business_info) | |
product_info_serializable = convert_to_serializable(product_info) | |
if last_user_request: | |
iteration_history += f"**درخواست کاربر:** {last_user_request}\n" | |
else: | |
last_user_request = original_user_request if original_user_request else "بهینه کن" # پیشفرض بهینهسازی | |
dce_instructions = f""" | |
iteration {iteration_count}: پرامپت قبلی رو بر اساس درخواست کاربر بررسی کن: | |
- اگه 'بهینه کن' بود، پرامپت رو سادهتر کن (تکرارها رو حذف کن) و Informations اضافی (مثل آدرس، قیمتها، جزئیات ارسال) رو به پایگاه دانش یا FAQ منتقل کن، ولی رفتار پرامپت ۱۰۰٪ مثل اولیه بمونه. | |
- اگه تغییر بود (مثل 'محصول اضافه کن')، فقط بخشهای مرتبط رو اصلاح کن و بقیه رو بدون تغییر برگردون. بهینهسازی انجام نده. | |
- همیشه نسخه کامل پرامپت، پایگاه دانش، و FAQ رو تولید کن. | |
""" | |
iteration_history += f"**دستورات DCE:** {dce_instructions}\n" | |
pee_prompt = f""" | |
{mother_prompt} | |
شما Prompt Engineering Expert (PEE) هستید: | |
اطلاعات کسبوکار: {json.dumps(business_info_serializable, ensure_ascii=False)} | |
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)} | |
پرامپت اولیه: {initial_prompt} | |
پرامپت فعلی: {prompt_output} | |
درخواست کاربر: {last_user_request} | |
تاریخچه: {iteration_history} | |
{dce_instructions} | |
خروجی رو با --- جدا کن (پرامپت --- پایگاه دانش --- FAQ). | |
""" | |
pee_response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=[{"role": "system", "content": pee_prompt}] | |
) | |
pee_output = pee_response.choices[0].message.content | |
iteration_history += f"**خروجی PEE:**\n{pee_output}\n" | |
parts = validate_and_fix_output(pee_output, prompt_output) | |
prompt_output = parts[0] | |
knowledge_base_output = parts[1] | |
faq_output = parts[2] | |
cae_prompt = f""" | |
{mother_prompt} | |
شما Critical Analysis Expert (CAE) هستید: | |
خروجی PEE: {pee_output} | |
پرامپت اولیه: {initial_prompt} | |
چک کن رفتار پرامپت اولیه حفظ شده باشه و درخواست کاربر اعمال شده باشه. | |
""" | |
cae_response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=[{"role": "system", "content": cae_prompt}] | |
) | |
iteration_history += f"**نقد CAE:**\n{cae_response.choices[0].message.content}\n" | |
dce_summary = f""" | |
**جمعبندی DCE:** iteration {iteration_count} تموم شد 😊 | |
**وضعیت فعلی:** {('همه درخواستها انجام شدن 🌟 اگه درخواست جدیدی نیست، "پایان" رو بزن تا خروجی نهایی رو ببینی.' if not last_user_request else 'درخواستها انجام شدن، اگه چیز دیگهای میخوای بگو!')} | |
**اهداف بعدی:** | |
#G-{iteration_count}-1: ادامه یا پایان. | |
**پایان iteration {iteration_count}** | |
""" | |
iteration_history += dce_summary | |
return (iteration_history, prompt_output, knowledge_base_output, faq_output, "", "", iteration_count, | |
gr.update(interactive=False), gr.update(interactive=True)) | |
# تابع پایان و تولید خروجی نهایی | |
def end_process(_=None): | |
global iteration_history, prompt_output, knowledge_base_output, faq_output, last_user_request, initial_prompt, original_user_request | |
business_info_serializable = convert_to_serializable(business_info) | |
product_info_serializable = convert_to_serializable(product_info) | |
if last_user_request: | |
iteration_history += f"**درخواست کاربر (فقط برای خروجی نهایی):** {last_user_request}\n" | |
else: | |
last_user_request = original_user_request | |
final_prompt = f""" | |
{mother_prompt} | |
فرایند iterationها تموم شده. خروجی نهایی رو تولید کن: | |
1. پرامپت چتبات به انگلیسی (Persona, Tone, Guidelines, ...). از پرامپت اولیه کاربر بهعنوان پایه استفاده کن. | |
- اگه درخواست 'بهینه کن' بوده، پرامپت رو سادهتر کن و اطلاعات اضافی رو به پایگاه دانش/FAQ منتقل کن، ولی رفتار ۱۰۰٪ مثل اولیه بمونه. | |
- اگه درخواست تغییر بوده، فقط بخشهای مرتبط رو اصلاح کن. | |
2. پایگاه دانش به فرمت JSON-like (name, description, variants, objectID). | |
3. FAQ به فرمت JSON-like (دستهبندیها، سوالات، جوابها). | |
اطلاعات کسبوکار: {json.dumps(business_info_serializable, ensure_ascii=False)} | |
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)} | |
پرامپت اولیه: {initial_prompt} | |
درخواست کاربر: {last_user_request} | |
تاریخچه iterationها: {iteration_history} | |
همیشه نسخه کامل هر سه بخش (پرامپت، پایگاه دانش، FAQ) رو تولید کن، هر بخش رو با --- جدا کن. | |
""" | |
final_response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=[{"role": "system", "content": final_prompt}] | |
) | |
final_output = final_response.choices[0].message.content | |
print("خروجی خام نهایی:", final_output) | |
parts = validate_and_fix_output(final_output, prompt_output) | |
prompt_output = parts[0] | |
knowledge_base_output = parts[1] | |
faq_output = parts[2] | |
iteration_history += "\n**فرایند تموم شد و خروجی نهایی آمادهست! 🎉**\n" | |
last_user_request = "" | |
return (iteration_history, prompt_output, knowledge_base_output, faq_output, "", "", "فرایند پایان یافت", | |
gr.update(interactive=True), gr.update(interactive=True)) | |
# تابع ریست فرایند | |
def reset_process(): | |
global iteration_count, iteration_history, prompt_output, knowledge_base_output, faq_output, business_info, product_info, last_user_request, initial_prompt, original_user_request | |
iteration_count = 0 | |
iteration_history = "" | |
prompt_output = "" | |
knowledge_base_output = "" | |
faq_output = "" | |
business_info = None | |
product_info = None | |
last_user_request = "" | |
initial_prompt = "" | |
original_user_request = "" | |
return ("", "", "", "", "", "", "فرایند ریست شد! حالا میتونی دوباره شروع کنی 😊", | |
gr.update(interactive=True), gr.update(interactive=True)) | |
# تابع ثبت درخواست کاربر | |
def submit_request(user_request): | |
global last_user_request, original_user_request | |
last_user_request = user_request.strip() | |
if not original_user_request: # اگه درخواست اولیه هنوز ثبت نشده | |
original_user_request = last_user_request | |
return "", "درخواستت ثبت شد! حالا 'ادامه دهید' رو بزن 😊" | |
# رابط کاربری Gradio | |
with gr.Blocks(title="سیستم نوا 🌟") as demo: | |
gr.Markdown("# سیستم نوا 🌟") | |
with gr.Row(): | |
file1 = gr.File(label="فرم اطلاعات اولیه (اختیاری)") | |
file2 = gr.File(label="فرم محصولات/خدمات (اختیاری)") | |
with gr.Row(): | |
user_prompt_box = gr.Textbox(label="پرامپت آماده شما (اختیاری)", lines=5, placeholder="پرامپت خودتون رو اینجا بذارید") | |
with gr.Row(): | |
user_request_box = gr.Textbox(label="درخواست شما", placeholder="مثلاً: 'محصول اضافه کن' یا 'بهینه کن'") | |
submit_request_btn = gr.Button("ارسال درخواست") | |
status_box = gr.Textbox(label="وضعیت فعلی", value="فرایند شروع نشده", interactive=False) | |
iteration_box = gr.Textbox(label="تاریخچه Iteration", lines=10) | |
with gr.Row(): | |
start_btn = gr.Button("شروع", interactive=True) | |
continue_btn = gr.Button("ادامه دهید") | |
end_btn = gr.Button("پایان") | |
reset_btn = gr.Button("ریست فرایند") | |
with gr.Tabs(): | |
with gr.TabItem("پرامپت"): | |
prompt_box = gr.Textbox(label="پرامپت (انگلیسی)") | |
with gr.TabItem("پایگاه دانش"): | |
kb_box = gr.Textbox(label="پایگاه دانش (JSON)") | |
with gr.TabItem("پرسش و پاسخ"): | |
faq_box = gr.Textbox(label="پرسش و پاسخ (JSON)") | |
# اتصال توابع | |
start_btn.click( | |
start_process, | |
inputs=[file1, file2, user_request_box, user_prompt_box], | |
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, user_prompt_box, status_box, start_btn, continue_btn] | |
) | |
continue_btn.click( | |
continue_iteration, | |
inputs=[], | |
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, user_prompt_box, status_box, start_btn, continue_btn] | |
) | |
end_btn.click( | |
end_process, | |
inputs=[], | |
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, user_prompt_box, status_box, start_btn, continue_btn] | |
) | |
reset_btn.click( | |
reset_process, | |
inputs=[], | |
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, user_prompt_box, status_box, start_btn, continue_btn] | |
) | |
submit_request_btn.click( | |
submit_request, | |
inputs=[user_request_box], | |
outputs=[user_request_box, status_box] | |
) | |
demo.launch() |