File size: 18,853 Bytes
f62816d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2326209
e49d754
0fb21e2
f62816d
0fb21e2
f62816d
 
0fb21e2
 
 
 
 
f62816d
 
481d8a9
f62816d
 
 
 
 
 
 
 
 
481d8a9
a17bae5
6486f6e
f62816d
6486f6e
 
2326209
a17bae5
f62816d
 
2326209
200b7f8
 
 
 
a17bae5
 
200b7f8
2326209
200b7f8
2326209
 
f62816d
 
e986435
f62816d
 
54056ee
 
f62816d
 
 
1847bad
a17bae5
f62816d
85a091c
0fb21e2
 
1847bad
f62816d
 
 
 
 
bd3a505
0fb21e2
1847bad
 
e49d754
54056ee
fb48488
da7b5e1
 
 
 
0fb21e2
fb48488
f62816d
 
 
 
0fb21e2
f62816d
 
da7b5e1
 
 
 
f62816d
da7b5e1
 
 
e49d754
f62816d
 
 
 
 
 
 
 
a17bae5
e49d754
 
 
 
f62816d
 
0fb21e2
 
 
da7b5e1
 
 
 
 
 
f62816d
 
 
 
 
0fb21e2
f62816d
 
0fb21e2
 
f62816d
0fb21e2
f62816d
 
 
 
e49d754
481d8a9
f62816d
e986435
2326209
a17bae5
f62816d
 
 
 
 
bd3a505
0fb21e2
a17bae5
0fb21e2
54056ee
fb48488
0fb21e2
 
 
 
fb48488
f62816d
 
 
 
0fb21e2
f62816d
 
0fb21e2
 
 
 
f62816d
e49d754
f62816d
 
 
 
 
 
 
 
a17bae5
e986435
 
 
 
f62816d
 
0fb21e2
 
 
 
f62816d
 
 
 
 
0fb21e2
f62816d
 
 
0fb21e2
f62816d
0fb21e2
f62816d
 
 
 
0fb21e2
e49d754
f62816d
e986435
2326209
a17bae5
f62816d
 
 
 
bd3a505
 
a17bae5
 
54056ee
f62816d
 
0fb21e2
 
 
 
e49d754
 
f62816d
 
0fb21e2
 
 
 
f62816d
 
 
 
 
 
6486f6e
f62816d
a17bae5
f62816d
 
 
 
 
2326209
bd3a505
e49d754
 
85a091c
 
 
a17bae5
85a091c
 
 
 
 
 
 
bd3a505
1847bad
a17bae5
1847bad
481d8a9
f62816d
bd3a505
 
a17bae5
0fb21e2
a17bae5
0fb21e2
bd3a505
 
f62816d
85a091c
f62816d
 
85a091c
 
 
 
1847bad
 
 
0fb21e2
85a091c
 
 
f62816d
85a091c
 
 
 
 
 
 
 
 
 
 
 
 
 
f62816d
85a091c
6486f6e
 
1847bad
 
6486f6e
 
 
bd3a505
1847bad
6486f6e
 
 
bd3a505
1847bad
1330e3d
 
 
 
1847bad
1330e3d
 
 
 
 
 
 
 
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
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()