77import time
88
99import gradio as gr
10+ from gradio_sandboxcomponent import SandboxComponent
1011import numpy as np
1112
1213from fastchat .constants import (
3031 get_model_description_md ,
3132)
3233from fastchat .serve .remote_logger import get_remote_logger
34+ from fastchat .serve .sandbox .code_runner import DEFAULT_SANDBOX_INSTRUCTION , create_chatbot_sandbox_state , on_click_run_code , update_sandbox_config
3335from fastchat .utils import (
3436 build_logger ,
3537 moderation_filter ,
@@ -152,7 +154,10 @@ def share_click(state0, state1, model_selector0, model_selector1, request: gr.Re
152154
153155
154156def add_text (
155- state0 , state1 , model_selector0 , model_selector1 , text , request : gr .Request
157+ state0 , state1 ,
158+ model_selector0 , model_selector1 ,
159+ sandbox_state0 , sandbox_state1 ,
160+ text , request : gr .Request
156161):
157162 ip = get_ip (request )
158163 logger .info (f"add_text (named). ip: { ip } . len: { len (text )} " )
@@ -204,6 +209,10 @@ def add_text(
204209 * 6
205210 )
206211
212+ # add snadbox instructions if enabled
213+ if sandbox_state0 ['enable_sandbox' ]:
214+ text = f"> { sandbox_state0 ['sandbox_instruction' ]} \n \n " + text
215+
207216 text = text [:INPUT_CHAR_LEN_LIMIT ] # Hard cut-off
208217 for i in range (num_sides ):
209218 states [i ].conv .append_message (states [i ].conv .roles [0 ], text )
@@ -227,6 +236,8 @@ def bot_response_multi(
227236 temperature ,
228237 top_p ,
229238 max_new_tokens ,
239+ sandbox_state0 ,
240+ sandbox_state1 ,
230241 request : gr .Request ,
231242):
232243 logger .info (f"bot_response_multi (named). ip: { get_ip (request )} " )
@@ -251,6 +262,7 @@ def bot_response_multi(
251262 top_p ,
252263 max_new_tokens ,
253264 request ,
265+ sandbox_state = sandbox_state0 ,
254266 )
255267 )
256268
@@ -327,7 +339,7 @@ def build_side_by_side_ui_named(models):
327339
328340 states = [gr .State () for _ in range (num_sides )]
329341 model_selectors = [None ] * num_sides
330- chatbots = [None ] * num_sides
342+ chatbots : list [ gr . Chatbot | None ] = [None ] * num_sides
331343
332344 notice = gr .Markdown (notice_markdown , elem_id = "notice_markdown" )
333345
@@ -366,6 +378,38 @@ def build_side_by_side_ui_named(models):
366378 ],
367379 )
368380
381+ # sandbox states and components
382+ sandbox_states : list [gr .State | None ] = [None for _ in range (num_sides )]
383+ sandboxes_components : list [tuple [
384+ gr .Markdown , # sandbox_output
385+ SandboxComponent , # sandbox_ui
386+ gr .Code , # sandbox_code
387+ ] | None ] = [None for _ in range (num_sides )]
388+
389+ with gr .Group ():
390+ with gr .Row ():
391+ for chatbotIdx in range (num_sides ):
392+ with gr .Column (scale = 1 ):
393+ sandbox_state = gr .State (create_chatbot_sandbox_state ())
394+ # Add containers for the sandbox output
395+ sandbox_title = gr .Markdown (value = f"### Model { chatbotIdx + 1 } Sandbox" , visible = True )
396+ with gr .Tab (label = "Output" ):
397+ sandbox_output = gr .Markdown (value = "" , visible = False )
398+ sandbox_ui = SandboxComponent (
399+ value = ("" , "" ),
400+ show_label = True ,
401+ visible = False ,
402+ )
403+ with gr .Tab (label = "Code" ):
404+ sandbox_code = gr .Code (value = "" , interactive = False , visible = False )
405+
406+ sandbox_states [chatbotIdx ] = sandbox_state
407+ sandboxes_components [chatbotIdx ] = (
408+ sandbox_output ,
409+ sandbox_ui ,
410+ sandbox_code ,
411+ )
412+
369413 with gr .Row ():
370414 leftvote_btn = gr .Button (
371415 value = "👈 A is better" , visible = False , interactive = False
@@ -378,6 +422,30 @@ def build_side_by_side_ui_named(models):
378422 value = "👎 Both are bad" , visible = False , interactive = False
379423 )
380424
425+
426+ # chatbox sandbox global config
427+ with gr .Group ():
428+ with gr .Row ():
429+ enable_sandbox_checkbox = gr .Checkbox (value = False , label = "Enable Sandbox" , interactive = True )
430+ sandbox_env_choice = gr .Dropdown (choices = ["React" , "Auto" ], label = "Sandbox Environment" , interactive = True )
431+ with gr .Group ():
432+ with gr .Accordion ("Sandbox Instructions" , open = False ):
433+ sandbox_instruction_textarea = gr .TextArea (
434+ value = DEFAULT_SANDBOX_INSTRUCTION
435+ )
436+
437+ # update sandbox global config
438+ enable_sandbox_checkbox .change (
439+ fn = update_sandbox_config ,
440+ inputs = [
441+ enable_sandbox_checkbox ,
442+ sandbox_env_choice ,
443+ sandbox_instruction_textarea ,
444+ * sandbox_states
445+ ],
446+ outputs = [* sandbox_states ]
447+ )
448+
381449 with gr .Row ():
382450 textbox = gr .Textbox (
383451 show_label = False ,
@@ -452,7 +520,7 @@ def build_side_by_side_ui_named(models):
452520 regenerate , states , states + chatbots + [textbox ] + btn_list
453521 ).then (
454522 bot_response_multi ,
455- states + [temperature , top_p , max_output_tokens ],
523+ states + [temperature , top_p , max_output_tokens ] + sandbox_states ,
456524 states + chatbots + btn_list ,
457525 ).then (
458526 flash_buttons , [], btn_list
@@ -488,25 +556,38 @@ def build_side_by_side_ui_named(models):
488556
489557 textbox .submit (
490558 add_text ,
491- states + model_selectors + [textbox ],
559+ states + model_selectors + sandbox_states + [textbox ],
492560 states + chatbots + [textbox ] + btn_list ,
493561 ).then (
494562 bot_response_multi ,
495- states + [temperature , top_p , max_output_tokens ],
563+ states + [temperature , top_p , max_output_tokens ] + sandbox_states ,
496564 states + chatbots + btn_list ,
497565 ).then (
498566 flash_buttons , [], btn_list
499567 )
500568 send_btn .click (
501569 add_text ,
502- states + model_selectors + [textbox ],
570+ states + model_selectors + sandbox_states + [textbox ],
503571 states + chatbots + [textbox ] + btn_list ,
504572 ).then (
505573 bot_response_multi ,
506- states + [temperature , top_p , max_output_tokens ],
574+ states + [temperature , top_p , max_output_tokens ] + sandbox_states ,
507575 states + chatbots + btn_list ,
508576 ).then (
509577 flash_buttons , [], btn_list
510578 )
511579
580+ for chatbotIdx in range (num_sides ):
581+ chatbot = chatbots [chatbotIdx ]
582+ state = states [chatbotIdx ]
583+ sandbox_state = sandbox_states [chatbotIdx ]
584+ sandbox_components = sandboxes_components [chatbotIdx ]
585+
586+ # trigger sandbox run
587+ chatbot .select (
588+ fn = on_click_run_code ,
589+ inputs = [state , sandbox_state , * sandbox_components ],
590+ outputs = [* sandbox_components ],
591+ )
592+
512593 return states + model_selectors
0 commit comments