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() |