Spaces:
Running
Running
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 = "" | |
# پرامپت مادر (بدون تغییر) | |
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. | |
... | |
""" | |
# تابع برای تبدیل دادهها به فرمت 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): | |
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 "پرامپت تولید نشد 😔" | |
kb_part = parts[1] if len(parts) > 1 else "پایگاه دانش تولید نشد 😕" | |
faq_part = parts[2] if len(parts) > 2 else "FAQ تولید نشد 🥳" | |
if not prompt_part.strip(): | |
prompt_part = "پرامپت خالیه 😔" | |
if not kb_part.strip(): | |
kb_part = "پایگاه دانش خالیه 😕" | |
if not faq_part.strip(): | |
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): | |
global iteration_count, iteration_history, business_info, product_info, last_user_request | |
iteration_count = 1 | |
iteration_history = "سلام عزیزم! فرایند شروع شد! 😍\n" | |
last_user_request = user_request | |
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"**درخواست کاربر (فقط برای این Iteration):** {last_user_request}\n" | |
dce_instructions = f"iteration {iteration_count}: لطفاً یه پرامپت به انگلیسی (با بخشهای Persona, Tone, Guidelines, About Us و غیره)، پایگاه دانش به فرمت JSON (با name, description, variants, objectID) و FAQ به فرمت JSON (با دستهبندی و جوابهای کوتاه و دوستانه) بسازید. اگه درخواست کاربر وجود داره، فقط توی این Iteration اعمالش کن." | |
iteration_history += f"**دستورات DCE:** {dce_instructions}\n" | |
pee_prompt = f""" | |
{mother_prompt} | |
شما Prompt Engineering Expert (PEE) هستید. بر اساس اطلاعات زیر و درخواست کاربر، پرامپت، پایگاه دانش و FAQ رو بسازید: | |
اطلاعات کسبوکار: {json.dumps(business_info_serializable, ensure_ascii=False)} | |
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)} | |
درخواست کاربر (فقط برای این Iteration): {last_user_request if last_user_request else "هیچ درخواستی وارد نشده"} | |
{dce_instructions} | |
خروجی رو با --- جدا کنید. | |
""" | |
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" | |
cae_prompt = f""" | |
{mother_prompt} | |
شما Critical Analysis Expert (CAE) هستید. خروجی PEE رو نقد کنید، مطمئن شید لحن درست اعمال شده، ساختار JSON درسته و درخواست کاربر (اگه هست) رعایت شده: | |
خروجی PEE:\n{pee_output} | |
""" | |
cae_response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=[{"role": "system", "content": cae_prompt}] | |
) | |
cae_output = cae_response.choices[0].message.content | |
iteration_history += f"**نقد CAE:**\n{cae_output}\n" | |
dce_summary = f""" | |
**جمعبندی DCE:** iteration {iteration_count} تموم شد 🌟 | |
**وضعیت فعلی:** پرامپت، پایگاه دانش و FAQ اولیه ساخته شدن. | |
**اهداف بعدی:** | |
#G-{iteration_count}-1: بهبود لحن و جزئیات بر اساس نقد CAE. | |
#G-{iteration_count}-2: تکمیل فرمت JSON. | |
**پایان iteration {iteration_count}** | |
""" | |
iteration_history += dce_summary | |
last_user_request = "" | |
return (iteration_history, "", "", "", "", 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 | |
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"**درخواست کاربر (فقط برای این Iteration):** {last_user_request}\n" | |
dce_instructions = f"iteration {iteration_count}: لطفاً خروجی قبلی رو بر اساس نقد CAE بهبود بدید، لحن رو دوستانهتر کنید (مگر اینکه درخواست کاربر چیز دیگهای بگه) و فرمت JSON رو دقیقتر کنید. اگه درخواست کاربر وجود داره، فقط توی این Iteration اعمالش کن." | |
iteration_history += f"**دستورات DCE:** {dce_instructions}\n" | |
pee_prompt = f""" | |
{mother_prompt} | |
شما Prompt Engineering Expert (PEE) هستید. خروجی قبلی رو بر اساس نقد CAE و درخواست کاربر بهبود بدید: | |
اطلاعات کسبوکار: {json.dumps(business_info_serializable, ensure_ascii=False)} | |
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)} | |
درخواست کاربر (فقط برای این Iteration): {last_user_request if last_user_request else "هیچ درخواستی وارد نشده"} | |
تاریخچه iteration قبلی:\n{iteration_history} | |
{dce_instructions} | |
خروجی رو با --- جدا کنید. | |
""" | |
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 = parts[0] | |
knowledge_base_output = parts[1] | |
faq_output = parts[2] | |
cae_prompt = f""" | |
{mother_prompt} | |
شما Critical Analysis Expert (CAE) هستید. خروجی جدید PEE رو نقد کنید و مطمئن شید لحن درست اعمال شده، فرمت JSON درسته و درخواست کاربر (اگه هست) رعایت شده: | |
خروجی PEE:\n{pee_output} | |
""" | |
cae_response = client.chat.completions.create( | |
model="gpt-4o", | |
messages=[{"role": "system", "content": cae_prompt}] | |
) | |
cae_output = cae_response.choices[0].message.content | |
iteration_history += f"**نقد CAE:**\n{cae_output}\n" | |
dce_summary = f""" | |
**جمعبندی DCE:** iteration {iteration_count} تموم شد 😊 | |
**وضعیت فعلی:** خروجیها بهبود یافتن. | |
**اهداف بعدی:** | |
#G-{iteration_count}-1: ادامه بهبود یا اتمام فرایند. | |
**پایان iteration {iteration_count}** | |
""" | |
iteration_history += dce_summary | |
last_user_request = "" | |
return (iteration_history, prompt_output, knowledge_base_output, faq_output, "", | |
f"Iteration {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 | |
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" | |
final_prompt = f""" | |
{mother_prompt} | |
فرایند iterationها تموم شده. لطفاً خروجی نهایی رو به این ترتیب تولید کنید: | |
1. پرامپت چتبات به انگلیسی با بخشهای: | |
- Persona | |
- Tone | |
- Guidelines | |
- About Us | |
- Responses to Common Questions | |
- Contact Information | |
- Additional Guidelines | |
لحن باید دوستانه، عامیانه، کوتاه (زیر 100 کلمه) و با ایموجیهای جذاب باشه مگر اینکه درخواست کاربر چیز دیگهای بگه. | |
--- | |
2. پایگاه دانش به فرمت JSON-like با فیلدهای: name, description, variants (شامل size و price), objectID. برای هر محصول یا خدمت یه ورودی جدا بساز. | |
--- | |
3. FAQ به فرمت JSON-like با دستهبندیها (مثل Services, Care)، موضوعات، سوالات و جوابهای کوتاه و دوستانه. | |
اطلاعات کسبوکار: {json.dumps(business_info_serializable, ensure_ascii=False)} | |
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)} | |
درخواست کاربر (فقط برای این مرحله): {last_user_request if last_user_request else "هیچ درخواستی وارد نشده"} | |
تاریخچه iterationها:\n{iteration_history} | |
**هر بخش رو با دقیقاً "---" جدا کن. هیچ متن اضافی قبل، بعد یا بین بخشها نذار.** | |
""" | |
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 = parts[0] | |
knowledge_base_output = parts[1] | |
faq_output = parts[2] | |
print("پرامپت نهایی:", prompt_output) | |
print("پایگاه دانش نهایی:", knowledge_base_output) | |
print("FAQ نهایی:", faq_output) | |
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 | |
iteration_count = 0 | |
iteration_history = "" | |
prompt_output = "" | |
knowledge_base_output = "" | |
faq_output = "" | |
business_info = None | |
product_info = None | |
last_user_request = "" | |
return ("", "", "", "", "", "فرایند ریست شد! حالا میتونی دوباره شروع کنی 😊", | |
gr.update(interactive=True), gr.update(interactive=True)) | |
# تابع ثبت درخواست کاربر | |
def submit_request(user_request): | |
global last_user_request | |
last_user_request = 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_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], | |
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_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, status_box, start_btn, continue_btn] | |
) | |
end_btn.click( | |
end_process, | |
inputs=[], | |
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_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, status_box, start_btn, continue_btn] | |
) | |
submit_request_btn.click( | |
submit_request, | |
inputs=[user_request_box], | |
outputs=[user_request_box, status_box] | |
) | |
demo.launch() |