File size: 21,913 Bytes
faae14e
5d7b9c1
 
 
 
f7d951f
5d7b9c1
 
 
 
 
f7d951f
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f7d951f
6f324bd
 
5d7b9c1
 
 
 
 
 
 
 
 
f7d951f
 
916d30d
 
 
 
 
5c9916f
916d30d
5d7b9c1
 
f7d951f
5d7b9c1
 
 
 
08e6713
 
 
 
 
5d7b9c1
08e6713
 
 
 
5d7b9c1
 
f7d951f
 
5d7b9c1
 
 
 
 
6972fdf
5d7b9c1
 
 
 
 
 
 
6972fdf
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
d102326
916d30d
5c9916f
f7d951f
5d7b9c1
82d5065
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96dbf5b
 
 
 
 
6972fdf
5d7b9c1
6972fdf
5d7b9c1
 
 
 
 
 
6972fdf
5d7b9c1
 
 
 
 
 
 
 
 
 
6972fdf
5d7b9c1
 
 
 
 
 
 
6972fdf
 
 
 
 
 
 
 
f7d951f
6972fdf
 
 
 
 
 
 
 
 
 
5d7b9c1
 
6972fdf
5d7b9c1
f7d951f
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
 
96dbf5b
78f21f0
145e258
 
 
5d7b9c1
0aa6368
f7d951f
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d99a747
61d8933
78f21f0
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261292c
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2bed347
5d7b9c1
 
 
 
 
 
d102326
beffdc5
d102326
 
 
 
 
 
 
5d7b9c1
 
 
d86bae2
6972fdf
d86bae2
 
5d7b9c1
 
 
 
 
 
 
58f973a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d7b9c1
 
 
58f973a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6972fdf
d102326
 
ebd60c0
 
 
 
58f973a
5d7b9c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0513f6f
5130a8b
6f324bd
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
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
import gradio as gr 
import sys
import subprocess
import os
sys.path.append("./")
sys.path.append("../")
import BotSimulator
from BotSimulator import TootBot
import openai
from io import StringIO
import multiprocessing
restore_point=sys.stdout


if not os.path.exists("data/fake-tweets"):
    os.makedirs("data/fake-tweets")
if not os.path.exists("data/failed-tweets"):
    os.makedirs("data/failed-tweets")
if not os.path.exists("images"):
    os.makedirs("images")


title = """<h1 align="center">🔥Fake Tweet Bot Simulation App 🔥</h1>"""
subtitle_1 = """<h2 align="center">Initialize Bot</h2>"""
subtitle_2 = """<h2 align="center">Run bot simulation</h2>"""
image_tokens_list = ["black and white", "year 2023", "cartoon", "animated",
                     "comic", "propaganda", "news", "classic disney style",
                     "holliemengert artstyle"]
topic_prompt_default = "Write a short tweet with less than 500 characters as if you were a real person with social media lingo and hashtags on this topic: "
# pool = multiprocessing.Pool()
# num_processes = pool._processes
global tootbot_app


def init_app(api_key,
             model_name,
             model_class,
             temperature,
             diffusion_model,
             keyword_model,
             dtype,
             topic_prompt):

    try:
        openai.api_key = api_key
        openai.Model.list()
    except Exception as e:
        raise gr.Error("Invalid API Key... " + str(e))

    console_logs = StringIO()
    sys.stdout = console_logs
    model_class = model_class.replace(" ", "").lower()
    global tootbot_app
    tootbot_app = TootBot(model=model_name,
                          model_class=model_class,
                          temperature=temperature)
    with open("client_cred.secret", "w") as file:
        file.write(os.getenv("MASTODON_CLIENT_SECRET"))
        file.close()
    tootbot_app.mastodon_login(username=os.getenv("MASTODON_USERNAME"),
                       password=os.getenv("MASTODON_PASSWORD"),
                       redirect_uri="http://localhost:8080",
                       client_id="client_cred.secret",
                       to_file="usercred.secret")
    os.remove("usercred.secret")
    os.remove("client_cred.secret")
    os.environ["OPENAI_API_KEY"] = api_key
    os.environ["OPENAI_API_KEY_2"] = api_key
    tootbot_app.topic_prescript = topic_prompt.strip() + " "
    tootbot_app.init_models(diffusion_model=diffusion_model,
                            keyword_model=keyword_model,
                            text_fail_classifier="davidna22/text-failed-classifier",
                            dtype=dtype,
                            device="cuda")
    return {
        progress_output: "### Current Progress \n Model Initialized Successfully! Time to Run the Simulation",
        log_output: console_logs.getvalue(),
        main_block_step_1: gr.update(visible=False),
        main_block_step_2: gr.update(visible=True),
        init_btn: gr.update(visible=False),
        run_sim_btn: gr.update(visible=True)
    }


def run_simulation(topic,
                   save=True,
                   num_responses=50,
                   n=10,
                   system_prompt=BotSimulator.assistant_prompt,
                   with_images=True,
                   img_mode="default",
                   augment_mode="default",
                   image_every_n_posts=10,
                   image_subtoken="Provide a realistic photograph. ",
                   image_tokens=[],
                   news_company="CNN",
                   text_model_name="gpt-3.5-turbo-0301"):
    if topic == "":
        raise gr.Error("Topic must not be empty")

    console_logs = StringIO()
    sys.stdout = console_logs
    filename = topic.replace(" ", "-") + ".csv"
    tweet_folder="data/fake-tweets"
    tweet_failfolder="data/failed-tweets"
    image_folder = "images"
    if not save:
        tweet_filename = ""
    else:
        tweet_filename = tweet_folder + "/" + filename

    if n > num_responses:
        n = num_responses

    if image_every_n_posts > num_responses:
        image_every_n_posts = num_responses

    tootbot_app.run(topic,
                    system_prompt=system_prompt,
                    num_responses=num_responses,
                    n=n,
                    save=save,
                    filename=filename,
                    tweet_folder=tweet_folder,
                    tweet_failfolder=tweet_failfolder,
                    with_images=with_images,
                    img_mode=img_mode,
                    augment_mode=augment_mode,
                    news_company=news_company,
                    image_every_n_posts=image_every_n_posts,
                    image_tokens=image_tokens,
                    image_subtoken=image_subtoken,
                    text_model_name=text_model_name,
                    image_folder=image_folder)

    subfolder = topic.replace(" ", "-")
    if with_images:
        img_filename = f"{image_folder}/{subfolder}/tweet-img-row-0.png"
        img_fullpath = os.path.join(os.path.dirname(__file__), img_filename)
    else:
        img_fullpath = gr.update(visible=False)
    sys.stdout = restore_point
    return {
        progress_output: "### Current Progress \n To see your results, visit the bot simulation Mastodon server. \n Link to Mastodon Server: [https://bot-simulation-research.app/home](https://bot-simulation-research.app/home)",
        log_output: console_logs.getvalue(),
        simulation_output_box: gr.update(visible=True),
        saved_file: tweet_filename,
        example_image: img_fullpath
    }


def toggle_image_params(with_images):
    if with_images:
        return {
            image_params: gr.update(visible=True)
        }
    else:
        return {
            image_params: gr.update(visible=False)
        }


def add_token_func(add_token):
    image_tokens_list.append(add_token)
    return {
        image_tokens: gr.update(choices=image_tokens_list, interactive=True)
    }


def reset_app():
    sys.stdout = restore_point
    console_logs = StringIO()
    return {
        progress_output: gr.update(value="### Current Progress <br>"),
        log_output: console_logs.getvalue(),
        api_key: gr.update(value=""),
        topic: gr.update(value=""),
        topic_prompt: gr.update(value=topic_prompt_default),
        with_images: gr.update(value=False),
        image_params: gr.update(visible=False),
        main_block_step_1: gr.update(visible=True),
        main_block_step_2: gr.update(visible=False),
        simulation_output_box: gr.update(visible=False),
        run_sim_btn: gr.update(visible=False),
        init_btn: gr.update(visible=True)
    }


with gr.Blocks() as demo:
    gr.HTML(title)
    demo_state = gr.State("Terms")
    with gr.Column(elem_id="main_block", visible=False) as main_block:
        with gr.Column(elem_id="main_block_step_1", visible=True) as main_block_step_1:
            gr.HTML(value=subtitle_1)
            api_key = gr.Textbox(label="Enter your API key")
            model_class = gr.Dropdown(value="Open AI",
                                      choices=["Open AI"],
                                      label="Select your Model Class (Only Open AI is supported as of now)")
            model_name = gr.Dropdown(value="gpt-3.5-turbo-0301",
                                     label="Select your Model",
                                     choices=["gpt-3.5-turbo",
                                              "gpt-3.5-turbo-0301",
                                              "gpt-4",
                                              "gpt-4-0314",
                                              "gpt-4-32k",
                                              "gpt-4-32k-0314"])
            temperature = gr.Slider(label="Set Your Temperature (0.0-1.7) WARNING: Temperature above 1.5 tends to produce gibberish 50% of the time.",
                                    value=1.4,
                                    minimum=0.0,
                                    maximum=1.7,
                                    step=0.1)
            with gr.Accordion("Additional Parameters", open=False):
                topic_prompt = gr.Textbox(label="Enter the Topic Prompt (Default Example below, Make sure the prompt has a ':' at the end):",
                                          value=topic_prompt_default)
                diffusion_model = gr.Dropdown(value="stabilityai/stable-diffusion-2-1-base",
                                              choices=["stabilityai/stable-diffusion-2-1-base",
                                                       "stabilityai/stable-diffusion-2-base",
                                                       "runwayml/stable-diffusion-v1-5",
                                                       "prompthero/openjourney",
                                                       "ogkalu/Comic-Diffusion",
                                                       "nitrosocke/classic-anim-diffusion"
                                                      ],
                                              label="Select your Image Diffusion Model")
                keyword_model = gr.Dropdown(value="ml6team/keyphrase-extraction-distilbert-inspec",
                                            choices=["ml6team/keyphrase-extraction-distilbert-inspec",
                                                     "ml6team/keyphrase-generation-keybart-inspec",
                                                     "ml6team/keyphrase-extraction-distilbert-kptimes",
                                                     "ml6team/keyphrase-extraction-kbir-inspec",
                                                     "ml6team/keyphrase-extraction-kbir-kpcrowd",
                                                    ],
                                            label="Select your Keyphrase Extraction Model")
                dtype = gr.Dropdown(value="float32",
                                    choices=["float32", "float16"],
                                    label="Select the torch datatype (float32 or float16)")

        with gr.Column(elem_id="main_block_step_2", visible=False) as main_block_step_2:
            gr.HTML(value=subtitle_2)
            gr.Markdown("Tweet Generation Parameters")
            topic = gr.Textbox(label="Enter the topic to Generate tweets (Ex: \"The Earth is Flat\")")
            save = gr.Checkbox(label="Download Generated Tweets CSV? (Y/n)", value=True)
            with gr.Accordion("Additional Parameters", open=False):
                num_responses = gr.Slider(label= "Number of total fake Tweets to generate", value=20, minimum=10, maximum=500, step=5)
                n = gr.Slider(label="Number of Tweets to return per API call (smaller = More randomized answers)", value=1, minimum=1, maximum=50, step=1)
                system_prompt = gr.Dropdown(label="Select the system prompt for the model (This is what Open AI uses to assist the model in text generation):",
                                            value=BotSimulator.assistant_prompt,
                                            choices=[
                                                BotSimulator.assistant_prompt,
                                                BotSimulator.prompt_DAN
                                            ],
                                            allow_custom_value="True")

            gr.Markdown("Image Generation Parameters")
            with_images = gr.Checkbox(label="Generate Images with tweets? (Y/n)", value=False)

            with gr.Column(elem_id="image_params", visible=False) as image_params:
                img_mode_label = """Image mode can be one of three types:
                \t 1) Default: Image generated using the topic specified
                \t 2) News: Prompt is generated by first creating a fake news article. Then generating a title for that article.
                \t 3) Keyword: Prompt is generated using a keyword extractor model
                """
                gr.Markdown(img_mode_label)
                img_mode = gr.Dropdown(show_label=False,
                                       value="Default",
                                       choices=[
                                           "Default",
                                           "News",
                                           "Keyword"])
                augment_mode_label = """Augment mode can be one of three types:
                \t 1) Default: Image generated without augmentations
                \t 2) News: Image generated using a fake news template
                \t 3) Screenshot: Image generated using a news screenshot template
                """
                gr.Markdown(augment_mode_label)
                augment_mode = gr.Dropdown(show_label=False,
                                           value="Default",
                                           choices=[
                                               "Default",
                                               "News",
                                               "Screenshot"])
                image_every_n_posts = gr.Slider(label="Generate images every \"n\" tweets (Control how many tweets are with images or not)",
                                                value=10, minimum=1, maximum=100, step=1)

                with gr.Accordion("Additional Parameters", open=False):
                    image_subtoken = gr.Dropdown(label="Select the intial style prompt for the Image Model. More in-depth prompts can be added in next parameter.",
                                                 allow_custom_value=True,
                                                 value="Provide a realistic photograph, ",
                                                 choices=[
                                                     "Provide a realistic photograph, ",
                                                     "Provide a drawing, ",
                                                     "Provide a portrait, ",])

                    with gr.Column():
                        gr.Markdown("Image style prompt tokens to add to the Image Diffusion Model. Allows for more customizable Images.")
                        with gr.Row():
                            with gr.Column(scale=4):
                                add_tokens = gr.Textbox(label="Add an image style prompt token to the list below")
                            with gr.Column(scale=1):
                                gr.Markdown("<br>")
                                add_token_btn = gr.Button("Add Token")
                        image_tokens = gr.CheckboxGroup(show_label=False, interactive=True,
                                                        choices=image_tokens_list)
                        add_token_btn.click(add_token_func, add_tokens, [image_tokens])

                    news_company = gr.Dropdown(label="News Company Logo to use",
                                               value="CNN",
                                               choices=[
                                                   "CNN"])
                    text_model_name = gr.Dropdown(value="gpt-3.5-turbo-0301",
                                                  label="Select Text Model to use",
                                                  choices=["gpt-3.5-turbo",
                                                           "gpt-3.5-turbo-0301",
                                                           "gpt-4",
                                                           "gpt-4-0314",
                                                           "gpt-4-32k",
                                                           "gpt-4-32k-0314"])
            with_images.change(toggle_image_params, with_images, [image_params])

        with gr.Row(elem_id="progress_box") as progress_box:
            with gr.Column():
                progress_output = gr.Markdown("### Current Progress <br>")
            with gr.Column():
                log_output = gr.Textbox(every=0.5, label="Logs", lines=8)

        with gr.Row(elem_id="simulation_output_box", visible=False) as simulation_output_box:
            saved_file = gr.File(label="List of Generated Tweets (CSV)")
            example_image = gr.Image(label="Example Image from generation", type="pil")

        with gr.Row(elem_id="run_sim_btn", visible=False) as run_sim_btn:
            submit_btn = gr.Button("Run Simulation")
            submt_process = submit_btn.click(run_simulation,
                                             inputs=[topic,
                                                     save,
                                                     num_responses,
                                                     n,
                                                     system_prompt,
                                                     with_images,
                                                     img_mode,
                                                     augment_mode,
                                                     image_every_n_posts,
                                                     image_subtoken,
                                                     image_tokens,
                                                     news_company,
                                                     text_model_name],
                                             outputs=[progress_output,
                                                      log_output,
                                                      simulation_output_box,
                                                      saved_file,
                                                      example_image])

        with gr.Row(elem_id="init_btn", visible=True) as init_btn:
            submit_btn = gr.Button("Initialize Bot")
            submt_process = submit_btn.click(init_app,
                                             inputs=[api_key,
                                                     model_name,
                                                     model_class,
                                                     temperature,
                                                     diffusion_model,
                                                     keyword_model,
                                                     dtype,
                                                     topic_prompt],
                                             outputs=[progress_output,
                                                      log_output,
                                                      main_block_step_1,
                                                      main_block_step_2,
                                                      init_btn,
                                                      run_sim_btn])

        with gr.Row(elem_id="reset_block", visible=True) as reset_block:
            reset_btn = gr.Button("Reset")
            reset_btn.click(reset_app, inputs=[], outputs=[progress_output, log_output, api_key,
                                                           topic, topic_prompt, with_images, image_params,
                                                           main_block_step_1, main_block_step_2,
                                                           simulation_output_box,
                                                           run_sim_btn, init_btn], cancels=[submt_process])

    with gr.Column(elem_id = "user_consent_container") as user_consent_block:
        accept_checkbox = gr.Checkbox(visible=False)
        js = "(x) => confirm('By clicking \"OK\", I agree that my data may be published or shared.')"
        with gr.Accordion("User Consent for Data Collection, Use, and Sharing", open=True):
            gr.HTML("""
            <div>
                <p>By using our app, which is powered by OpenAI's API, you acknowledge and agree to the following terms regarding the data you provide:</p>
                <ol>
                    <li><strong>Collection:</strong> We may collect information, including the inputs you type into our app, the outputs generated by OpenAI's API, and certain technical details about your device and connection (such as browser type, operating system, and IP address) provided by your device's request headers.</li>
                    <li><strong>Use:</strong> We may use the collected data for research purposes, to improve our services, and to develop new products or services, including commercial applications, and for security purposes, such as protecting against unauthorized access and attacks.</li>
                    <li><strong>Sharing and Publication:</strong> Your data, including the technical details collected from your device's request headers, may be published, shared with third parties, or used for analysis and reporting purposes.</li>
                    <li><strong>Data Retention:</strong> We may retain your data, including the technical details collected from your device's request headers, for as long as necessary.</li>
                </ol>
                <p>By continuing to use our app, you provide your explicit consent to the collection, use, and potential sharing of your data as described above. If you do not agree with our data collection, use, and sharing practices, please do not use our app.</p>
            </div>
            """)
            accept_button = gr.Button("I Agree")

        def enable_inputs():
            return user_consent_block.update(visible=False), main_block.update(visible=True)

    accept_button.click(None, None, accept_checkbox, _js=js, queue=False)
    accept_checkbox.change(fn=enable_inputs, inputs=[], outputs=[user_consent_block, main_block], queue=False)

    # demo.queue(concurrency_count=1, max_size=num_processes)
    demo.queue(concurrency_count=1)
    demo.launch(share=False, show_api=False)