File size: 15,485 Bytes
f62816d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2326209
f62816d
85a091c
f62816d
 
85a091c
f62816d
 
481d8a9
f62816d
 
 
 
 
 
 
 
 
481d8a9
f62816d
6486f6e
f62816d
6486f6e
 
2326209
f62816d
 
 
2326209
 
 
 
 
 
 
 
f62816d
 
e986435
f62816d
 
54056ee
 
f62816d
 
 
54056ee
bd3a505
f62816d
85a091c
2326209
f62816d
 
 
 
 
bd3a505
 
54056ee
6486f6e
f62816d
 
 
 
54056ee
f62816d
 
bd3a505
f62816d
 
 
 
 
 
 
 
 
 
 
 
e986435
f62816d
 
 
 
 
 
 
 
 
 
 
 
 
6486f6e
f62816d
 
 
 
2326209
f62816d
481d8a9
 
f62816d
e986435
2326209
bd3a505
f62816d
 
 
 
 
bd3a505
 
54056ee
e986435
f62816d
 
 
 
54056ee
f62816d
 
bd3a505
f62816d
 
 
 
 
 
 
 
 
 
 
e986435
 
 
 
 
f62816d
 
e986435
f62816d
 
 
 
 
 
 
 
 
 
 
 
 
6486f6e
f62816d
 
 
2326209
f62816d
481d8a9
 
f62816d
e986435
2326209
bd3a505
f62816d
 
 
 
bd3a505
 
54056ee
f62816d
 
 
 
 
 
 
 
 
 
 
e986435
f62816d
 
 
 
 
 
bd3a505
f62816d
85a091c
f62816d
 
 
 
 
 
6486f6e
f62816d
 
 
 
 
 
2326209
 
 
 
f62816d
2326209
bd3a505
481d8a9
 
85a091c
 
 
bd3a505
85a091c
 
 
 
 
 
 
bd3a505
481d8a9
 
f62816d
bd3a505
 
 
 
 
 
f62816d
85a091c
f62816d
 
85a091c
 
 
 
 
 
 
 
f62816d
85a091c
 
 
 
 
 
 
 
 
 
 
 
 
 
f62816d
85a091c
6486f6e
 
 
481d8a9
6486f6e
 
 
bd3a505
481d8a9
6486f6e
 
 
bd3a505
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
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()