imamnurby commited on
Commit
c518c3d
1 Parent(s): 61b1e15

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +503 -112
app.py CHANGED
@@ -1,142 +1,533 @@
 
1
  from transformers import AutoTokenizer
2
  from transformers import RobertaTokenizer, EncoderDecoderModel
3
- import pandas as pd
4
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
 
 
 
 
 
 
 
 
6
 
7
- model = EncoderDecoderModel.from_pretrained("imamnurby/rob2rand_chen_w_prefix_c_fc")
8
- tokenizer = RobertaTokenizer.from_pretrained("imamnurby/rob2rand_chen_w_prefix_c_fc")
 
 
 
 
 
 
9
 
10
- def generate_preds(desc, gen_mode, num_beams, num_returned_seqs):
11
- desc = desc.lower()
12
- if gen_mode=="Channel":
13
- desc = "GENERATE TRIGGER AND ACTION CHANNEL ONLY <pf> " + desc
14
- elif gen_mode=="Function":
15
- desc = "GENERATE BOTH CHANNEL AND FUNCTION FOR TRIGGER AND ACTION <pf> " + desc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- input_ids = tokenizer.encode(desc, return_tensors='pt')
18
-
19
- # activate beam search and early_stopping
20
- preds = model.generate(
21
- input_ids,
22
- max_length=100,
23
- num_beams=num_beams,
24
- num_return_sequences=num_returned_seqs,
25
- early_stopping=True
26
- )
27
-
28
- output_list = []
29
- for item in preds:
30
- output_list.append(tokenizer.decode(item, skip_special_tokens=True))
 
 
31
 
32
- if gen_mode=="Channel":
33
- trigger = [x.split("<sep>")[0].strip() for x in output_list]
34
- trigger_desc = ["dummy" for x in output_list]
35
- action = [x.split("<sep>")[1].strip() for x in output_list]
36
- action_desc = ["dummy" for x in output_list]
37
- df = {"Trigger": trigger,
38
- "Trigger Description": trigger_desc,
39
- "Action": action,
40
- "Action Description": action_desc
41
- }
42
- elif gen_mode=="Function":
43
- trigger = [x.split("<sep>")[1].strip() for x in output_list]
44
- trigger_desc = ["dummy" for x in output_list]
45
- action = [x.split("<sep>")[3].strip() for x in output_list]
46
- action_desc = ["dummy" for x in output_list]
47
- df = {"Trigger": trigger,
48
- "Trigger Description": trigger_desc,
49
- "Action": action,
50
- "Action Description": action_desc
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  return pd.DataFrame(df)
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- def generate_preds_field(desc_field, num_beams_field, num_returned_seqs_field):
56
- desc_field = desc_field.lower()
57
-
58
- input_ids = tokenizer.encode(desc_field, return_tensors='pt')
59
-
60
- # activate beam search and early_stopping
61
- preds = model.generate(
62
- input_ids,
63
- max_length=100,
64
- num_beams=num_beams_field,
65
- num_return_sequences=num_returned_seqs_field,
66
- early_stopping=True
67
- )
68
-
69
- output_list = []
70
- for item in preds:
71
- output_list.append(tokenizer.decode(item, skip_special_tokens=True))
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
- trigger = [x.split("<sep>")[0].strip() for x in output_list]
74
- trigger_desc = ["dummy" for x in output_list]
75
- trigger_fields = ["dummy" for x in output_list]
76
- action = [x.split("<sep>")[1].strip() for x in output_list]
77
- action_desc = ["dummy" for x in output_list]
78
- action_fields = ["dummy" for x in output_list]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  df = {"Trigger": trigger,
80
- "Trigger Description": trigger_desc,
81
- "Trigger Fields": trigger_fields,
82
- "Action": action,
83
- "Action Description": action_desc,
84
- "Action Fields": action_fields
85
- }
86
  return pd.DataFrame(df)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  demo = gr.Blocks()
90
  with demo:
91
- gr.Markdown("<h1><center>RecipeGen: Automated Trigger Action Programs (TAPs) Generation Tool</center></h1>")
92
  # gr.Markdown("This demo allows you to generate TAPs using functionality description described in English. You can learn the working detail of our tool from our paper")
93
- gr.Markdown("<h3>What are TAPs?</h3>")
94
  gr.Markdown("""
95
- TAPs or Trigger Action Programs are an event-driven rules used to automate smart devices and/or internet services. TAPs are written in the form of "IF **trigger** then execute **action**, where **trigger** and **action** refer to API calls. TAPs has been used in various use cases, ranging from home monitoring system to business workflow automation.
 
 
96
  """)
97
- gr.Markdown("<h3>Why generating TAPs can be challenging?</h3>")
98
- gr.Markdown("""
99
- Generating TAP is challenging mainly because of the large search space of the API calls that can be used as the trigger and action.
100
- """)
101
- gr.Markdown("<h3>RecipeGen</h3?>")
102
  gr.Markdown("""
103
- RecipeGen is a deep learning-based tool that can assist end-users to generate TAPs using natural language descriptions. End-users can describe the functionality of the intended TAP, then RecipeGen will generate the candidate TAPs based the description.
 
104
  """)
105
- gr.Markdown("<h3>Instructions</h3>")
106
  gr.Markdown("""
107
- 1. Select the generation granularity (i.e., Channel, Function, or Field)
108
- 2. Describe your intended functionality
109
- 3. Specify the beam width
110
- 4. Specify the number of returned sequences
111
- 5. Click **Generate**; the generated TAPs along with the description of each component will show in the **Results**
112
  """)
113
- gr.Markdown("NOTE: **#Returned Sequences** should be LESS THAN OR EQUAL **Beam Width**")
114
  with gr.Tabs():
115
- with gr.TabItem("Channel/Function"):
116
- with gr.Column():
117
- gen_mode = gr.Radio(label="Granularity", choices=["Channel", "Function"])
118
- desc = gr.Textbox(label="Functionality Description", placeholder="Describe the functionality here")
119
- num_beams = gr.Slider(minimum=2, maximum=500, value=10, step=1, label="Beam Width")
120
- num_returned_seqs = gr.Slider(minimum=2, maximum=500, value=10, step=1, label="#Returned Sequences")
121
- generate = gr.Button("Generate")
122
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  with gr.Box():
124
- gr.Markdown("<h3><center>Results</center></h3>")
125
- gr.Markdown("<br>")
126
- results = gr.Dataframe(headers=["Trigger", "Trigger Description", "Action", "Action Description"])
127
-
128
- with gr.TabItem("Field"):
129
- with gr.Column():
130
- desc_field = gr.Textbox(label="Functionality Description", placeholder="Describe the functionality here")
131
- num_beams_field = gr.Slider(minimum=2, maximum=500, value=10, step=1, label="Beam Width")
132
- num_returned_seqs_field = gr.Slider(minimum=2, maximum=500, value=10, step=1, label="#Returned Sequences")
133
- generate_field = gr.Button("Generate")
134
 
135
  with gr.Box():
136
- gr.Markdown("<h3><center>Results</center></h3>")
137
- gr.Markdown("<br>")
138
- results_field = gr.Dataframe(headers=["Trigger", "Trigger Description", "Trigger Fields", "Action", "Action Description", "Action Fields"])
139
-
140
- generate.click(generate_preds, inputs=[desc, gen_mode, num_beams, num_returned_seqs], outputs=[results])
141
- generate_field.click(generate_preds_field, inputs=[desc_field, num_beams_field, num_returned_seqs_field], outputs=[results_field])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  demo.launch()
 
1
+ import pandas as pd
2
  from transformers import AutoTokenizer
3
  from transformers import RobertaTokenizer, EncoderDecoderModel
 
4
  import gradio as gr
5
+ import string
6
+ from utils import (get_metadata,
7
+ append_prefix,
8
+ append_suffix,
9
+ process_field)
10
+
11
+ metadata = "../dataset/metadata.csv"
12
+ channel_dict, function_dict_trigger, function_dict_action, field_mapping, valid_field, channel_to_function_dict = get_metadata(path=metadata)
13
+
14
+ tokenizer = RobertaTokenizer.from_pretrained("imamnurby/rob2rand_merged_w_prefix_c_fc_field")
15
+
16
+ model_oneshot = EncoderDecoderModel.from_pretrained("imamnurby/rob2rand_merged_w_prefix_c_fc_field")
17
+ model_interactive = EncoderDecoderModel.from_pretrained("imamnurby/rob2rand_merged_w_prefix_c_fc_interactive")
18
+
19
+
20
+ ###
21
+ # INTERACTIVE GENERATION FUNCTIONS
22
+ ###
23
+ def return_same(input_desc):
24
+ return input_desc
25
+
26
+ def update_dropdown_trig_ch(df_result):
27
+ list_result = []
28
+ answer = ''
29
+ for ind in df_result.index:
30
+ if str(df_result['No.'][ind]) != '':
31
+ answer = str(df_result['No.'][ind])+ ' - '+ str(df_result['Trigger Channel'][ind])
32
+ list_result.append(answer)
33
+ return gr.Dropdown.update(choices=list_result)
34
+
35
+ def update_dropdown_trig_func(df_result):
36
+ list_result = []
37
+ answer = ''
38
+ for ind in df_result.index:
39
+ if str(df_result['No.'][ind]) != '':
40
+ answer = str(df_result['No.'][ind])+ ' - '+ str(df_result['Trigger Function'][ind])
41
+ list_result.append(answer)
42
+ return gr.Dropdown.update(choices=list_result)
43
 
44
+ def update_dropdown_action_ch(df_result):
45
+ list_result = []
46
+ answer = ''
47
+ for ind in df_result.index:
48
+ if str(df_result['No.'][ind]) != '':
49
+ answer = str(df_result['No.'][ind])+ ' - '+ str(df_result['Action Channel'][ind])
50
+ list_result.append(answer)
51
+ return gr.Dropdown.update(choices=list_result)
52
 
53
+ def update_dropdown_action_func(df_result):
54
+ list_result = []
55
+ answer = ''
56
+ for ind in df_result.index:
57
+ if str(df_result['No.'][ind]) != '':
58
+ answer = str(df_result['No.'][ind])+ ' - '+ str(df_result['Action Function'][ind])
59
+ list_result.append(answer)
60
+ return gr.Dropdown.update(choices=list_result)
61
 
62
+ def set_trigger_ch(df_result, string_chosen):
63
+ index_chosen = string_chosen[0:1]
64
+ index_chosen = int(index_chosen)
65
+ return gr.Textbox.update(value = df_result.iloc[index_chosen-1]["Trigger Channel"])
66
+
67
+ def set_trig_func(df_result, string_chosen):
68
+ index_chosen = string_chosen[0:1]
69
+ index_chosen = int(index_chosen)
70
+ return gr.Textbox.update(value = df_result.iloc[index_chosen-1]["Trigger Function"])
71
+
72
+ def set_action_ch(df_result, string_chosen):
73
+ index_chosen = string_chosen[0:1]
74
+ index_chosen = int(index_chosen)
75
+ return gr.Textbox.update(value = df_result.iloc[index_chosen-1]["Action Channel"])
76
+
77
+ def set_final_result(tf, df_result, string_chosen):
78
+ index_chosen = string_chosen[0:1]
79
+ index_chosen = int(index_chosen)
80
+ af = df_result.iloc[index_chosen-1]["Action Function"]
81
+ tf_field = field_mapping.get(tf, "()")
82
+ tf = tf + tf_field
83
+ af_field = field_mapping.get(af, "()")
84
+ af = af + af_field
85
+ df_dict = {"Trigger": [tf],
86
+ "Action": [af]}
87
+ return pd.DataFrame(df_dict)
88
+
89
+ def generate_preds_tc(input_desc, n_beams_interactive):
90
+ count_arr = []
91
+ decoded_preds=[]
92
+ descriptions=[]
93
+ if input_desc!='':
94
+ desc = input_desc.lower()
95
+ desc = append_prefix(desc=desc,
96
+ prefix= "GENERATE TRIGGER CHANNEL <pf> ")
97
 
98
+ input_ids = tokenizer.encode(desc, return_tensors='pt')
99
+
100
+ preds = model_interactive.generate(input_ids,
101
+ max_length=200,
102
+ num_beams=n_beams_interactive,
103
+ num_return_sequences=n_beams_interactive,
104
+ early_stopping=True)
105
+ count = 0
106
+ for item in preds:
107
+ temp_pred = (tokenizer.decode(item, skip_special_tokens=True))
108
+ if temp_pred in channel_dict.keys():
109
+ count = count + 1
110
+ count_arr.append(count)
111
+ decoded_preds.append(temp_pred)
112
+ temp_desc = channel_dict.get(temp_pred, "null")
113
+ descriptions.append(temp_desc)
114
 
115
+ df = {'No.':count_arr,
116
+ 'Trigger Channel': decoded_preds,
117
+ 'Description': descriptions}
118
+ return pd.DataFrame(df)
119
+
120
+ def generate_preds_tf(input_desc, n_beams_interactive, selected_tc):
121
+ count_arr = []
122
+ decoded_preds=[]
123
+ descriptions=[]
124
+ if input_desc!='' and selected_tc!='':
125
+ desc = input_desc.lower()
126
+ desc = append_prefix(desc=desc,
127
+ prefix="GENERATE TRIGGER FUNCTION <pf> ")
128
+
129
+ desc = append_suffix(desc=desc,
130
+ suffix=f" <out> {selected_tc}")
131
+
132
+ input_ids = tokenizer.encode(desc, return_tensors='pt')
133
+
134
+ preds = model_interactive.generate(input_ids,
135
+ max_length=200,
136
+ num_beams=n_beams_interactive,
137
+ num_return_sequences=n_beams_interactive,
138
+ early_stopping=True)
139
+ count = 0
140
+ for item in preds:
141
+ temp_pred = (tokenizer.decode(item, skip_special_tokens=True))
142
+ if temp_pred in function_dict_trigger.keys():
143
+ temp_desc = function_dict_trigger.get(temp_pred, "null")
144
+ if selected_tc in temp_pred:
145
+ count = count + 1
146
+ count_arr.append(count)
147
+ decoded_preds.append(temp_pred)
148
+ descriptions.append(temp_desc)
149
+
150
+ df = {'No.': count_arr,
151
+ 'Trigger Function': decoded_preds,
152
+ 'Description': descriptions}
153
  return pd.DataFrame(df)
154
 
155
+ def generate_preds_ac(input_desc, n_beams_interactive, selected_tc, selected_tf):
156
+ count_arr = []
157
+ decoded_preds=[]
158
+ descriptions=[]
159
+ if input_desc!='' and selected_tf!='':
160
+ desc = input_desc.lower()
161
+ desc = append_prefix(desc=desc,
162
+ prefix= "GENERATE ACTION CHANNEL <pf> ")
163
+
164
+ desc = append_suffix(desc=desc,
165
+ suffix=f" <out> {selected_tc} {selected_tf}")
166
+
167
+ input_ids = tokenizer.encode(desc, return_tensors='pt')
168
+
169
+ preds = model_interactive.generate(input_ids,
170
+ max_length=200,
171
+ num_beams=n_beams_interactive,
172
+ num_return_sequences=n_beams_interactive,
173
+ early_stopping=True)
174
+ count = 0
175
+ for item in preds:
176
+ temp_pred = (tokenizer.decode(item, skip_special_tokens=True))
177
+ if temp_pred in channel_dict.keys():
178
+ count = count + 1
179
+ count_arr.append(count)
180
+ decoded_preds.append(temp_pred)
181
+ temp_desc = channel_dict.get(temp_pred, "null")
182
+ descriptions.append(temp_desc)
183
+
184
+ df = {'No.':count_arr,
185
+ 'Action Channel': decoded_preds,
186
+ 'Description': descriptions}
187
+ return pd.DataFrame(df)
188
 
189
+ def generate_preds_af(input_desc, n_beams_interactive, selected_tc, selected_tf, selected_ac):
190
+ count_arr = []
191
+ decoded_preds=[]
192
+ descriptions=[]
193
+ if input_desc!='' and selected_ac!='':
194
+ desc = input_desc.lower()
195
+ desc = append_prefix(desc=desc,
196
+ prefix="GENERATE TRIGGER FUNCTION <pf> ")
197
+
198
+ desc = append_suffix(desc=desc,
199
+ suffix=f" <out> {selected_tc} {selected_tf} {selected_ac}")
200
+
201
+ input_ids = tokenizer.encode(desc, return_tensors='pt')
202
+
203
+ preds = model_interactive.generate(input_ids,
204
+ max_length=200,
205
+ num_beams=n_beams_interactive,
206
+ num_return_sequences=n_beams_interactive,
207
+ early_stopping=True)
208
+ count = 0
209
+ for item in preds:
210
+ temp_pred = (tokenizer.decode(item, skip_special_tokens=True))
211
+ if temp_pred in function_dict_action.keys():
212
+ temp_desc = function_dict_action.get(temp_pred, "null")
213
+
214
+ if selected_ac in temp_pred:
215
+ count = count + 1
216
+ count_arr.append(count)
217
+ decoded_preds.append(temp_pred)
218
+ descriptions.append(temp_desc)
219
 
220
+ df = {'No.':count_arr,
221
+ 'Action Function': decoded_preds,
222
+ 'Description': descriptions}
223
+ df = pd.DataFrame(df)
224
+ df.index.names = ['Ranking']
225
+ return df
226
+ ###
227
+
228
+ ###
229
+ # ONESHOT GENERATION FUNCTIONS
230
+ ###
231
+ def generate_oneshot(input_desc, n_beams_oneshot):
232
+ trigger = []
233
+ trigger_desc = []
234
+ action = []
235
+ action_desc = []
236
+ if input_desc!='':
237
+ desc = input_desc.lower()
238
+ prefix="GENERATE ON THE FIELD-LEVEL GRANULARITY <pf> "
239
+ desc = append_prefix(desc=desc,
240
+ prefix=prefix)
241
+
242
+ input_ids = tokenizer.encode(desc, return_tensors='pt')
243
+
244
+ # activate beam search and early_stopping
245
+ preds = model_oneshot.generate(input_ids,
246
+ max_length=200,
247
+ num_beams=n_beams_oneshot,
248
+ num_return_sequences=n_beams_oneshot,
249
+ early_stopping=True)
250
+
251
+ decoded_preds = []
252
+ for item in preds:
253
+ decoded_preds.append(tokenizer.decode(item, skip_special_tokens=True))
254
+
255
+ for item in decoded_preds:
256
+ invalid_field = False
257
+ splitted_items = item.split("<sep>")
258
+ processed = []
259
+ if len(splitted_items)==6:
260
+ for idx, subitem in enumerate(splitted_items):
261
+ if idx!=2 or idx!=4:
262
+ subitem = subitem.strip()
263
+ processed.append(subitem)
264
+ assert(len(processed)==6)
265
+ temp_tf = processed[1]
266
+ temp_af = processed[4]
267
+
268
+ temp_tf_field = process_field(processed[2])
269
+ for field in temp_tf_field:
270
+ if field not in valid_field:
271
+ invalid_field = True
272
+ break
273
+ if invalid_field:
274
+ continue
275
+ temp_tf_field = "(" + ", ".join(temp_tf_field) + ")"
276
+
277
+ temp_af_field = process_field(processed[-1])
278
+ for field in temp_af_field:
279
+ if field not in valid_field:
280
+ invalid_field = True
281
+ break
282
+ if invalid_field:
283
+ continue
284
+ temp_af_field = "(" + ", ".join(temp_af_field) + ")"
285
+
286
+ if temp_tf in function_dict_trigger.keys() and temp_af in function_dict_action.keys():
287
+ temp_tf_desc = function_dict_trigger.get(temp_tf)
288
+ temp_af_desc = function_dict_action.get(temp_af)
289
+
290
+ temp_tf = temp_tf + temp_tf_field
291
+ temp_af = temp_af + temp_af_field
292
+
293
+ trigger.append(temp_tf)
294
+ trigger_desc.append(temp_tf_desc)
295
+
296
+ action.append(temp_af)
297
+ action_desc.append(temp_af_desc)
298
+
299
  df = {"Trigger": trigger,
300
+ "Action": action,
301
+ "Trigger Description": trigger_desc,
302
+ "Action Description": action_desc}
 
 
 
303
  return pd.DataFrame(df)
304
+ ###
305
+
306
+ ###
307
+ # DISCOVER FUNCTIONS
308
+ ###
309
+ def generate_channel(input_desc, n_beams_discover):
310
+ trigger = []
311
+ trigger_func = []
312
+ trigger_desc = []
313
+ action = []
314
+ action_func = []
315
+ action_desc = []
316
+ if input_desc!='':
317
+ desc = input_desc.lower()
318
+ prefix="GENERATE CHANNEL ONLY WITHOUT FUNCTION <pf> "
319
+ desc = append_prefix(desc=desc,
320
+ prefix=prefix)
321
 
322
+ input_ids = tokenizer.encode(desc, return_tensors='pt')
323
+
324
+ # activate beam search and early_stopping
325
+ preds = model_oneshot.generate(input_ids,
326
+ max_length=200,
327
+ num_beams=n_beams_discover,
328
+ num_return_sequences=n_beams_discover,
329
+ early_stopping=True)
330
+
331
+ decoded_preds = []
332
+ for item in preds:
333
+ decoded_preds.append(tokenizer.decode(item, skip_special_tokens=True))
334
+
335
+ for item in decoded_preds:
336
+ channels = item.split("<sep>")
337
+ channels = [ch.strip() for ch in channels]
338
+ if len(channels)==2:
339
+ if channels[0] in channel_dict.keys() and channels[1] in channel_dict.keys() and channels[0] in channel_to_function_dict.keys() and channels[1] in channel_to_function_dict.keys():
340
+ temp_tc_desc = channel_dict.get(channels[0])
341
+ trigger_desc.append(temp_tc_desc)
342
+ trigger.append(channels[0])
343
+ trigger_func.append(channel_to_function_dict.get(channels[0]))
344
+
345
+ temp_ac_desc = channel_dict.get(channels[1])
346
+ action_desc.append(temp_ac_desc)
347
+ action.append(channels[1])
348
+ action_func.append(channel_to_function_dict.get(channels[1]))
349
 
350
+ df_trigger = pd.DataFrame({"Trigger": trigger,
351
+ "Available Functions": trigger_func,
352
+ "Trigger Description": trigger_desc})
353
+
354
+ df_action = pd.DataFrame({"Action": action,
355
+ "Available Functions": action_func,
356
+ "Action Description": action_desc})
357
+
358
+ df_trigger.drop_duplicates(inplace=True)
359
+ df_action.drop_duplicates(inplace=True)
360
+
361
+ return pd.DataFrame(df_trigger), pd.DataFrame(df_action)
362
+
363
+ ###
364
+ # MAIN GRADIO APP
365
+ ###
366
  demo = gr.Blocks()
367
  with demo:
368
+ gr.Markdown("<h1><center>RecipeGen: an Automated Trigger Action Programs (TAPs) Generation Tool</center></h1>")
369
  # gr.Markdown("This demo allows you to generate TAPs using functionality description described in English. You can learn the working detail of our tool from our paper")
370
+ gr.Markdown("<h3>What is TAP?</h3>")
371
  gr.Markdown("""
372
+ TAPs or Trigger Action Programs are event-driven rules used to automate smart devices and/or internet services. TAPs are written in the form of "IF a **{trigger}** is
373
+ satisfied then execute an **{action}**, where the **{trigger}** and the **{action}** correspond to API calls. TAPs have been used in various use cases, ranging from home monitoring
374
+ system to business workflow automation.
375
  """)
376
+ gr.Markdown("<h3>What is RecipeGen?</h3>")
 
 
 
 
377
  gr.Markdown("""
378
+ RecipeGen is a deep learning-based tool that can assist end-users to generate TAPs using natural language description. End-users can describe the functionality of the intended TAP, then RecipeGen
379
+ will generate the TAP candidates based on the given description.
380
  """)
381
+ gr.Markdown("<h3>Working Mode</h3>")
382
  gr.Markdown("""
383
+ - Interactive: generate a TAP using step-by-step wizard
384
+ - One Click: generate a TAP using one click button
385
+ - Function Discovery: Discover relevant functionalities from channels with a similar functionalities
 
 
386
  """)
 
387
  with gr.Tabs():
388
+ with gr.TabItem("Interactive"):
389
+ gr.Markdown("<h3><center>Instructions for Interactive Mode</center></h3>")
390
+ gr.Markdown("""1. There are 5 generation steps, i.e., generating trigger channel, trigger function, action channel, action function, and the final TAP.
391
+ 2. **[STEP 1]** Describe the functionality in the `Functionality Description` text box. Click `Generate Trigger Channel` button. The channel candidates and their descriptions will show up in the `Trigger Channel Results` table.
392
+ 3. **[STEP 2]** Select a trigger channel from the dropdown `Select the Trigger Channel`. Click `Generate Trigger Function` button. The function candidates and their descriptions will show up in the `Trigger Function Results` table.
393
+ 4. **[STEP 3]** Select a trigger function from the dropdown `Select the Trigger Function`. Click `Generate Action Channel` button. The channel candidates and their descriptions will show up in the `Action Channel Results` table.
394
+ 5. **[STEP 4]** Select an action channel from the dropdown `Select the Action Channel`. Click `Generate Action Function` button. The function candidates and their descriptions will show up in the `Action Function Results` table.
395
+ 6. **[STEP 5]** Select an action function from the `Select the Action Function` to generate the final TAP.""")
396
+ gr.Markdown(""" NOTE: You can control how many sequences are returned by tuning the `Beam Width` slider. Larger value will cause longer generation time.
397
+ """)
398
+
399
+ with gr.Box():
400
+ with gr.Column():
401
+ dropdown_example = gr.Dropdown(type ="value",choices = ["Log to my spreadsheet if motion is detected in the living room","Notify me when someone open the front door", "Turn on my Philips lamp every sunset","Update my picture in Twitter when I change my profile picture in Facebook","Send and append to my note when I create a new bookmark"], label = "Here are some sample functionality descriptions that you can try")
402
+ button_use_example = gr.Button("Try this sample")
403
+
404
+ with gr.Box():
405
+ with gr.Column():
406
+
407
+ gr.Markdown("<h4><center>Step 1: Generate Trigger Channels</center></h4>")
408
+ textbox_input = gr.Textbox(label="Functionality Description", placeholder="Describe the functionality here")
409
+ n_beams_interactive = gr.Slider(minimum=2, maximum=100, value=20, step=1, label="Beam Width")
410
+ button_generate_tc = gr.Button("Generate Trigger Channels")
411
+
412
+ gr.Markdown("<br>")
413
+ gr.Markdown("<h4><center>Trigger Channel Results</center></h4>")
414
+ table_tc = gr.Dataframe(headers=["No.","Trigger Channel", "Description"], row_count=1)
415
+
416
  with gr.Box():
417
+ with gr.Column():
418
+
419
+ gr.Markdown("<h4><center>Step 2: Generate Trigger Functions</center></h4>")
420
+ dropdown_tc = gr.Dropdown(label="Select the Trigger Channel",type="value", choices=[''])
421
+ textbox_selected_tc = gr.Textbox(value="", visible=False)
422
+ button_generate_tf = gr.Button("Generate Trigger Functions")
423
+
424
+ gr.Markdown("<br>")
425
+ gr.Markdown("<h4><center>Trigger Function Results</center></h4>")
426
+ table_tf = gr.Dataframe(headers=["No.","Trigger Function", "Description"], row_count=1)
427
 
428
  with gr.Box():
429
+ with gr.Column():
430
+
431
+ gr.Markdown("<h4><center>Step 3: Generate Action Channels</center></h4>")
432
+ dropdown_tf = gr.Dropdown(label="Select the Trigger Function",type="value", choices=[''])
433
+ textbox_selected_tf = gr.Textbox(value="", visible=False)
434
+ button_generate_ac = gr.Button("Generate Action Channels")
435
+
436
+ gr.Markdown("<br>")
437
+ gr.Markdown("<h4><center>Action Channel Results</center></h4>")
438
+ table_ac = gr.Dataframe(headers=["No.","Action Channel", "Description"], row_count=1)
439
+
440
+ with gr.Box():
441
+ with gr.Column():
442
+ gr.Markdown("<h4><center>Step 4: Generate Action Functions</center></h4>")
443
+ dropdown_ac = gr.Dropdown(label="Select the Action Channel",type="value", choices=[''])
444
+ textbox_selected_ac = gr.Textbox(value="", visible=False)
445
+
446
+ button_generate_af = gr.Button("Generate Action Functions")
447
+ gr.Markdown("<br>")
448
+ gr.Markdown("<h4><center>Action Function Results</center></h4>")
449
+ table_af = gr.Dataframe(headers=["No.","Action Function", "Description"], row_count=1)
450
+
451
+ with gr.Box():
452
+ with gr.Column():
453
+ gr.Markdown("<h4><center>Step 5: Generate the Final TAP</center></h4>")
454
+ dropdown_af = gr.Dropdown(label="Select the Action Function",type="value", choices=[''])
455
+ table_final = gr.Dataframe(headers=["Trigger","Action"], row_count=1)
456
+
457
+ button_use_example.click(return_same, inputs=[dropdown_example], outputs=[textbox_input])
458
+ button_generate_tc.click(generate_preds_tc, inputs=[textbox_input, n_beams_interactive], outputs=[table_tc])
459
+
460
+ table_tc.change(fn=update_dropdown_trig_ch, inputs=[table_tc], outputs=[dropdown_tc])
461
+ dropdown_tc.change(fn=set_trigger_ch, inputs=[table_tc,dropdown_tc], outputs=[textbox_selected_tc])
462
+ button_generate_tf.click(generate_preds_tf, inputs=[textbox_input, n_beams_interactive, textbox_selected_tc], outputs=[table_tf])
463
+
464
+ table_tf.change(fn=update_dropdown_trig_func, inputs=[table_tf], outputs=[dropdown_tf])
465
+ dropdown_tf.change(fn=set_trig_func, inputs=[table_tf,dropdown_tf], outputs=[textbox_selected_tf])
466
+ button_generate_ac.click(generate_preds_ac, inputs=[textbox_input, n_beams_interactive, textbox_selected_tc, textbox_selected_tf], outputs=[table_ac])
467
+
468
+ table_ac.change(fn=update_dropdown_action_ch, inputs=[table_ac], outputs=[dropdown_ac])
469
+ dropdown_ac.change(fn=set_action_ch, inputs=[table_ac,dropdown_ac], outputs=[textbox_selected_ac])
470
+ button_generate_af.click(generate_preds_af, inputs=[textbox_input, n_beams_interactive, textbox_selected_tc, textbox_selected_tf, textbox_selected_ac], outputs=[table_af])
471
+
472
+ table_af.change(fn=update_dropdown_action_func, inputs=[table_af], outputs=[dropdown_af])
473
+ dropdown_af.change(fn=set_final_result, inputs=[textbox_selected_tf, table_af, dropdown_af], outputs=[table_final])
474
+
475
+ with gr.TabItem("One Click"):
476
+ gr.Markdown("<h3><center>Instructions for One Click Mode</center></h3>")
477
+ gr.Markdown("""
478
+ 1. Describe the functionality in the `Functionality Description` text box.
479
+ 2. Click `Generate TAP` button. The TAP candidates will show up in the `TAP Results` table. The table consists of 4 columns: Trigger, Action, Trigger Description, and Action Description. You can scroll the table vertically.
480
+ """)
481
+ gr.Markdown(""" NOTE: You can control how many sequences are returned by tuning the `Beam Width` slider. Larger value will cause longer generation time.""")
482
+
483
+ with gr.Box():
484
+ with gr.Column():
485
+ gr.Markdown("You can try some description samples below:")
486
+ dropdown_example = gr.Dropdown(type ="value",choices = ["Log to my spreadsheet if motion is detected in the living room","Notify me when someone open the front door", "Turn on my Philips lamp every sunset","Update my picture in Twitter when I change my profile picture in Facebook","Send and append to my note when I create a new bookmark"], label = "Here are some sample functionality descriptions that you can try")
487
+ button_use_example = gr.Button("Try this sample")
488
+
489
+ with gr.Box():
490
+ with gr.Column():
491
+ textbox_input = gr.Textbox(label="Functionality Description", placeholder="Describe the functionality here")
492
+ n_beams_oneshot = gr.Slider(minimum=2, maximum=100, value=20, step=1, label="Beam Width")
493
+ button_generate_oneshot = gr.Button("Generate TAPs")
494
+
495
+ gr.Markdown("<br>")
496
+ gr.Markdown("<h4><center>TAP Results</center></h4>")
497
+ table_oneshot = gr.Dataframe(headers=["Trigger", "Action", "Trigger Description", "Action Description"], row_count=1)
498
+
499
+ button_use_example.click(return_same, inputs=[dropdown_example], outputs=[textbox_input])
500
+ button_generate_oneshot.click(generate_oneshot, inputs=[textbox_input, n_beams_oneshot], outputs=[table_oneshot])
501
+
502
+ with gr.TabItem("Function Discovery"):
503
+ gr.Markdown("<h3><center>Instructions for One-shot Mode</center></h3>")
504
+ gr.Markdown("""
505
+ 1. Describe the functionality in the `Functionality Description` text box.
506
+ 2. Click `Discover Functioanlities` button. The table containing relevant trigger and action channels will show up. Each channel is accompanied by a list of available functionalities.
507
+ """)
508
+ gr.Markdown(""" NOTE: You can control how many sequences are returned by tuning the `Beam Width` slider. Larger value will cause longer generation time.""")
509
+
510
+ with gr.Box():
511
+ with gr.Column():
512
+ gr.Markdown("You can try some description samples below:")
513
+ dropdown_example = gr.Dropdown(type ="value",choices = ["Log to my spreadsheet if motion is detected in the living room","Notify me when someone open the front door", "Turn on my Philips lamp every sunset","Update my picture in Twitter when I change my profile picture in Facebook","Send and append to my note when I create a new bookmark"], label = "Here are some sample functionality descriptions that you can try")
514
+ button_use_example = gr.Button("Try this sample")
515
+
516
+ with gr.Box():
517
+ with gr.Column():
518
+ textbox_input = gr.Textbox(label="Functionality Description", placeholder="Describe the functionality here")
519
+ n_beams_discover = gr.Slider(minimum=2, maximum=100, value=20, step=1, label="Beam Width")
520
+ button_discover_function = gr.Button("Discover Functions!")
521
+
522
+ gr.Markdown("<br>")
523
+ gr.Markdown("<h4><center>Relevant Trigger Channels</center></h4>")
524
+ table_discover_tc = gr.Dataframe(headers=["Trigger", "Available Functions", "Trigger Description"], row_count=1)
525
+
526
+ gr.Markdown("<br>")
527
+ gr.Markdown("<h4><center>Relevant Action Channels</center></h4>")
528
+ table_discover_ac = gr.Dataframe(headers=["Action", "Available Functions", "Action Description"], row_count=1)
529
+
530
+ button_use_example.click(return_same, inputs=[dropdown_example], outputs=[textbox_input])
531
+ button_discover_function.click(generate_channel, inputs=[textbox_input, n_beams_discover], outputs=[table_discover_tc, table_discover_ac])
532
+
533
  demo.launch()