aail-hf/ensemble_machine
0
1import gradio as gr2from utils import *3from save_data import add_or_update_row_at_fixed_position, get_sheet_service4from instructions import *5from user_groups import user_data6from constants import SDG_DETAILS, WORD_LIMIT_MIN, WORD_LIMIT_MAX, GROUP_SEPERATION, LOCAL_PARAMS7from html_codes import *8 9class SessionManager:10 def __init__(self):11 self.sessions = {}12 13 def add_session(self, cooperate_style, task, identification_code):14 if cooperate_style == "sequential":15 session = {16 "user_identification_code": identification_code,17 "task": task,18 "cooperate_style": cooperate_style,19 "human_initial_answer": None,20 "ai_modificated_output": None,21 "evaluation": None22 }23 elif cooperate_style == "reverse_sequential":24 session = {25 "user_identification_code": identification_code,26 "task": task,27 "cooperate_style": cooperate_style,28 "ai_initial_answer": None,29 "human_modifications": None,30 "final_answer": None,31 "evaluation": None32 }33 elif cooperate_style == "parallel":34 session = { 35 "user_identification_code": identification_code,36 "task": task,37 "cooperate_style": cooperate_style,38 "ai_initial_answer": None,39 "human_initial_answer": None,40 "merged_final_answer": None,41 "evaluation": None42 }43 self.sessions[identification_code] = session44 return identification_code45 46 def update(self, index, output_content, key='final_output'):47 self.sessions[index][key] = output_content48 49 def get_session(self, index):50 return self.sessions[index]51 52 def save_session_to_sheet(self, index, service, SHEET_ID):53 session = self.sessions[index]54 row_id = int(index) % GROUP_SEPERATION + 2 # user data starts from row 255 new_row = list(session.values())56 add_or_update_row_at_fixed_position(57 row_id = row_id, 58 new_row = new_row, 59 service = service, 60 SPREADSHEET_ID = SHEET_ID, 61 num_of_columns=len(new_row)) 62 63 64 65def handle_create_sequential(task, human_input, session_manager, api_key, identification_code):66 cooperate_style = "sequential"67 session_index = session_manager.add_session(task=task, cooperate_style=cooperate_style, identification_code = identification_code)68 session_manager.update(session_index, human_input, 'human_initial_answer')69 session_manager.update(session_index, identification_code, 'user_identification_code')70 if word_limit_validation(human_input):71 output = word_limit_validation(human_input)72 else:73 output = merge_texts_sequential(task, human_input, api_key)74 session_manager.update(session_index, output, 'ai_modificated_output')75 return output, session_index76 77 78def handle_create_parallel(task, human_input, session_manager, api_key, identification_code):79 cooperate_style = "parallel"80 session_index = session_manager.add_session(task=task, cooperate_style=cooperate_style, identification_code = identification_code)81 if word_limit_validation(human_input):82 ai_initial_answer = word_limit_validation(human_input)83 final_answer = word_limit_validation(human_input)84 else:85 ai_initial_answer = generate_ai_initial_answer(task, api_key)86 final_answer = merge_texts_parallel(task, human_input, ai_initial_answer, api_key)87 session_manager.update(session_index, human_input, 'human_initial_answer')88 session_manager.update(session_index, ai_initial_answer, 'ai_initial_answer')89 session_manager.update(session_index, final_answer, 'merged_final_answer')90 session_manager.update(session_index, identification_code, 'user_identification_code')91 return ai_initial_answer, session_index92 93def handle_create_reverse_sequential(task, session_manager, api_key, identification_code):94 cooperate_style = "reverse_sequential"95 session_index = session_manager.add_session(task=task, cooperate_style=cooperate_style, identification_code = identification_code)96 ai_initial_answer = generate_ai_initial_answer(task, api_key)97 session_manager.update(session_index, ai_initial_answer, 'ai_initial_answer')98 session_manager.update(session_index, identification_code, 'user_identification_code')99 return ai_initial_answer, session_index100 101 102def handle_modify_reverse_sequential(session_index, modification_suggestions, session_manager, api_key):103 session = session_manager.get_session(session_index)104 session_manager.update(session_index, modification_suggestions, 'human_modifications')105 if word_limit_validation(modification_suggestions):106 final_answer = word_limit_validation(modification_suggestions)107 else:108 final_answer = modification_suggestions109 #final_answer = modify_with_suggestion(session['task'], modification_suggestions, api_key)110 session_manager.update(session_index, final_answer, 'final_answer')111 return final_answer, session_index112 113 114 115def evaluate_interaction(session_index, session_manager, api_key):116 session = session_manager.get_session(session_index)117 if session['cooperate_style'] == "sequential":118 evaluation = get_evaluation_with_gpt(session['task'], session['ai_modificated_output'], api_key)119 elif session['cooperate_style'] == "reverse_sequential":120 evaluation = get_evaluation_with_gpt(session['task'], session['final_answer'], api_key)121 elif session['cooperate_style'] == "parallel":122 evaluation = get_evaluation_with_gpt(session['task'], session['merged_final_answer'], api_key)123 session['evaluation'] = evaluation124 return evaluation125 126def save_data(session_index, session_manager, service, SHEET_ID):127 session_manager.save_session_to_sheet(session_index, service, SHEET_ID)128 return "Data has been saved to Google Sheets."129 130def login(identification_code):131 groups = ["A", "B", "C"]132 if not identification_code:133 return update_content(None)134 135 user_group_id = int(identification_code)//1000 136 if user_group_id in range(3):137 return update_content(groups[user_group_id])138 else:139 return update_content(None)140 141def word_limit_validation(human_input):142 words = human_input.split()143 if len(words) < WORD_LIMIT_MIN:144 return f"Error: Please enter at least 100 words."145 elif len(words) > WORD_LIMIT_MAX:146 return f"Error: Please enter less than 500 words."147 return None148 149def on_textbox_change(session_index, session_manager, service, SHEET_ID):150 return save_data(session_index, session_manager, service, SHEET_ID)151 152def update_word_count(text):153 words = text.split()154 return f"Word Count: {len(words)}"155 156def check_initial_generated(initial_answer):157 if not initial_answer:158 gr.Warning("Please click 'Create' to generate the AI output first.")159 return None160 161if __name__ == "__main__":162 api_key = get_api_key(local=LOCAL_PARAMS)163 service, SHEET_IDs = get_sheet_service(local=LOCAL_PARAMS)164 SHEET_ID1, SHEET_ID2, SHEET_ID3 = SHEET_IDs165 166 session_manager = SessionManager()167 168 with gr.Blocks(fill_width=True,169 css = background_css,170 js = no_copy_paste_js171 ) as app:172 title = gr.HTML("<h1 style='color: white;'> Human-AI Ensemble </h1>")173 with gr.Row():174 identification_code = gr.Textbox(label="Enter your identification code")175 login_button = gr.Button("Login")176 experiment_notes = gr.Textbox(label ="Reward & Bonus",177 value = notes_for_participants())178 login_status = gr.Textbox(label="Next Tasks", interactive=False)179 group = gr.State()180 181 with gr.Column(visible=False) as task:182 description = gr.Textbox(label="Task Description", 183 value = default_task_description(),184 interactive=False, 185 lines=12)186 187 with gr.Accordion(label = "Click to See 17 SDGs", 188 open=False):189 gr.Markdown(SDG_DETAILS)190 191 # initialization of different group contents192 group_a_content = gr.Group(visible=False, elem_id="group-a")193 group_b_content = gr.Group(visible=False, elem_id="group-b")194 group_c_content = gr.Group(visible=False, elem_id="group-c")195 196 197 198 199 def update_content(group):200 if group == "A":201 return gr.update(visible=True), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), group_a_instructions()202 elif group == "B":203 return gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), group_b_instructions()204 elif group == "C":205 return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), group_c_instructions()206 else:207 return gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), invalid_group()208 209 login_button.click(login, inputs=identification_code, outputs=[task, group_a_content, group_b_content, group_c_content, login_status])210 211 212 213 with group_a_content:214 with gr.Row():215 human_input = gr.Textbox(label="Enter each idea on a new line (Shift+Enter), starting with '1', '2', and '3'.", placeholder="Please propose 3 ideas to help Airbnb’s business model align with 17 SDGs (At least 100 words)")216 word_count_display_a = gr.Label(value="Word count: 0")217 human_input.change(fn=update_word_count, inputs=human_input, outputs=word_count_display_a)218 with gr.Row():219 submit_btn = gr.Button("Submit & See AI Output")220 with gr.Row():221 ai_output = gr.Textbox(label="AI Output", interactive=False)222 session_index = gr.Number(label="Session Index", visible=False)223 224 submit_btn.click(225 fn=lambda task, human_input, id: handle_create_sequential(task, human_input, session_manager, api_key, id),226 inputs=[description, human_input, identification_code],227 outputs=[ai_output, session_index]228 )229 230 231 232 # Evaluate without showing 233 evaluation_result = gr.Textbox(label="Evaluation Result", visible=False, interactive = False)234 235 ai_output.change(236 fn=lambda session_index: evaluate_interaction(session_index, session_manager, api_key),237 inputs=[session_index],238 outputs=[evaluation_result]239 )240 241 evaluation_result.change(242 fn = lambda session_index: on_textbox_change(session_index, session_manager, service, SHEET_ID1),243 inputs = [session_index]244 )245 246 save_btn = gr.Button("Save Data", elem_id="save_btn")247 save_result = gr.Label()248 249 250 save_btn.click(251 fn=lambda session_index: save_data(session_index, session_manager, service, SHEET_ID1),252 inputs=[session_index],253 outputs=[save_result]254 )255 256 257 with group_b_content:258 # gr.HTML("<p>Group B Content</p>")259 with gr.Row():260 create_initial_btn = gr.Button("Create")261 with gr.Row():262 initial_answer = gr.Textbox(label="AI Output", interactive=False)263 with gr.Row():264 modification_suggestions = gr.Textbox(label="Please refine AI's three ideas as your final answer, starting with '1', '2', and '3'.", placeholder="Please propose 3 ideas to help Airbnb’s business model align with 17 SDGs (At least 100 words)")265 word_count_display_b = gr.Label(value="Word count: 0")266 modification_suggestions.change(fn=update_word_count, inputs=modification_suggestions, outputs=word_count_display_b)267 modification_suggestions.change(fn=check_initial_generated, inputs = [initial_answer] )268 with gr.Row():269 create_final_btn = gr.Button("Review")270 with gr.Row():271 final_answer = gr.Textbox(label="Final Answer", interactive=False)272 session_index = gr.Number(label="Session Index", visible=False)273 274 275 create_initial_btn.click(276 fn=lambda task, id: handle_create_reverse_sequential(task, session_manager, api_key, id),277 inputs=[description, identification_code],278 outputs=[initial_answer, session_index]279 )280 281 initial_answer.change(282 fn = lambda session_index: on_textbox_change(session_index, session_manager, service, SHEET_ID3),283 inputs = [session_index]284 )285 286 create_final_btn.click(287 fn=lambda session_index, modification_suggestions: handle_modify_reverse_sequential(session_index, modification_suggestions, session_manager, api_key),288 inputs=[session_index, modification_suggestions],289 outputs=[final_answer, session_index]290 )291 292 293 #evaluate_btn = gr.Button("Evaluate")294 evaluation_result = gr.Textbox(label="Evaluation Result", visible=False, interactive=False)295 296 final_answer.change(297 fn=lambda session_index: evaluate_interaction(session_index, session_manager, api_key),298 inputs=[session_index],299 outputs=[evaluation_result]300 )301 302 evaluation_result.change(303 fn = lambda session_index: on_textbox_change(session_index, session_manager, service, SHEET_ID3),304 inputs = [session_index]305 )306 307 save_btn = gr.Button("Save Data", elem_id="save_btn")308 save_result = gr.Label()309 310 save_btn.click(311 fn=lambda session_index: save_data(session_index, session_manager, service, SHEET_ID3),312 inputs=[session_index],313 outputs=[save_result]314 )315 316 317 318 with group_c_content:319 with gr.Row():320 human_input = gr.Textbox(label="Enter each idea on a new line (Shift+Enter), starting with '1', '2', and '3'.", placeholder="Please propose 3 ideas to help Airbnb’s business model align with 17 SDGs (At least 100 words)")321 word_count_display_c = gr.Label(value="Word count: 0")322 human_input.change(fn=update_word_count, inputs=human_input, outputs=word_count_display_c)323 with gr.Row():324 create_btn = gr.Button("Submit & See AI Output")325 with gr.Row(): 326 ai_initial_output = gr.Textbox(label="AI Output Generated Independently", interactive=False)327 with gr.Row():328 merge_btn = gr.Button("Merge Using the Second AI")329 with gr.Row():330 final_output = gr.Textbox(label="Final Merged Output", interactive=False)331 session_index = gr.Number(label="Session Index", visible=False)332 333 create_btn.click(334 fn=lambda task, human_input, id: handle_create_parallel(task, human_input, session_manager, api_key, id),335 inputs=[description, human_input, identification_code],336 outputs=[ai_initial_output, session_index]337 )338 339 merge_btn.click(340 fn= lambda session_index : display_merged_output(session_index, session_manager),341 inputs = [session_index],342 outputs=[final_output]343 )344 345 346 #evaluate_btn = gr.Button("Evaluate")347 evaluation_result = gr.Textbox(label="Evaluation Result", visible=False, interactive = False)348 349 final_output.change(350 fn=lambda session_index: evaluate_interaction(session_index, session_manager, api_key),351 inputs=[session_index],352 outputs=[evaluation_result]353 )354 355 evaluation_result.change(356 fn = lambda session_index: on_textbox_change(session_index, session_manager, service, SHEET_ID2),357 inputs = [session_index]358 )359 360 save_btn = gr.Button("Save Data",elem_id="save_btn")361 save_result = gr.Label()362 363 save_btn.click(364 fn=lambda session_index: save_data(session_index, session_manager, service, SHEET_ID2),365 inputs=[session_index],366 outputs=[save_result]367 )368 369 370 app.launch(share=True)371 