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