|
from typing import Dict, List, Optional, NamedTuple, Type, Union |
|
|
|
|
|
import gradio as gr |
|
|
|
|
|
MAX_INPUTS = 10 |
|
MAX_TASKS = 50 |
|
|
|
|
|
class Input: |
|
def render(self, visible: bool) -> gr.Row: |
|
with gr.Row(visible=visible) as gr_component: |
|
self.output_name = gr.Textbox( |
|
label="Input name (can be referenced with {})", |
|
interactive=True, |
|
placeholder="Variable name", |
|
) |
|
self.output = gr.Textbox( |
|
label="Input value", |
|
interactive=True, |
|
placeholder="Variable value", |
|
) |
|
return gr_component |
|
|
|
|
|
class AITask: |
|
@property |
|
def vars(self): |
|
return [self.prompt] |
|
|
|
def render(self, visible: bool) -> gr.Box: |
|
with gr.Box(visible=visible) as gr_component: |
|
gr.Markdown(f"AI task") |
|
with gr.Row(): |
|
with gr.Column(): |
|
self.prompt = gr.Textbox( |
|
label="Instructions", |
|
lines=13, |
|
interactive=True, |
|
placeholder="What is the AI assistant meant to do?", |
|
) |
|
with gr.Column(): |
|
self.output_name = gr.Textbox( |
|
label="Output name (can be referenced with {})", |
|
interactive=True, |
|
placeholder="Variable name", |
|
) |
|
self.output = gr.Textbox( |
|
show_label=False, |
|
lines=10, |
|
interactive=False, |
|
) |
|
return gr_component |
|
|
|
|
|
class Component: |
|
def __init__(self, id_: int, internal: Union[Input, AITask], visible: bool = False): |
|
|
|
self._id = id_ |
|
self.internal = internal |
|
self.visible = visible |
|
|
|
|
|
self.component_id: gr.Textbox |
|
self.source: gr.Textbox |
|
self.gr_component = gr.Box |
|
self.output_name: gr.Textbox |
|
self.output: gr.Textbox |
|
|
|
def render(self) -> None: |
|
self.component_id = gr.Textbox(value=str(self._id), visible=False) |
|
self.source = gr.Textbox(value=self.internal.__class__.__name__, visible=False) |
|
self.gr_component = self.internal.render(bool(self.visible)) |
|
self.output_name = self.internal.output_name |
|
self.output = self.internal.output |
|
|
|
|
|
class Variable(NamedTuple): |
|
source: Type[Union[Input, AITask]] |
|
id_: int |
|
name: str |
|
value: str |
|
|
|
|
|
all_inputs = {i: Component(i, Input()) for i in range(MAX_INPUTS)} |
|
all_tasks = {i: Component(i, AITask()) for i in range(MAX_TASKS)} |
|
|
|
all_inputs[0].visible = True |
|
all_tasks[0].visible = True |
|
|
|
|
|
def add_input() -> Optional[List[Dict]]: |
|
for i, input_ in all_inputs.items(): |
|
if not input_.visible: |
|
input_.visible = True |
|
return [gr.Row.update(visible=True)] * (i + 1) + [ |
|
gr.Row.update(visible=False) |
|
] * (MAX_INPUTS - i) |
|
|
|
|
|
def remove_input() -> Optional[List[Dict]]: |
|
for i, input_ in reversed(all_inputs.items()): |
|
if input_.visible: |
|
input_.visible = False |
|
return [gr.Row.update(visible=True)] * i + [ |
|
gr.Row.update(visible=False) |
|
] * (MAX_INPUTS - i + 1) |
|
|
|
|
|
def add_task() -> Optional[List[Dict]]: |
|
for i, task in all_tasks.items(): |
|
if not task.visible: |
|
task.visible = True |
|
return [gr.Box.update(visible=True)] * (i + 1) + [ |
|
gr.Box.update(visible=False) |
|
] * (MAX_TASKS - i) |
|
|
|
|
|
def remove_task() -> Optional[List[Dict]]: |
|
for i, task in reversed(all_tasks.items()): |
|
if task.visible: |
|
task.visible = False |
|
return [gr.Box.update(visible=True)] * i + [ |
|
gr.Box.update(visible=False) |
|
] * (MAX_TASKS - i + 1) |
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
|
for i in all_inputs.values(): |
|
i.render() |
|
input_error = gr.HighlightedText( |
|
[("Repeated variable names in inputs. Please pick different names.", "Error")], |
|
show_label=False, |
|
visible=False, |
|
) |
|
with gr.Row(): |
|
add_input_btn = gr.Button("Add input variable") |
|
remove_input_btn = gr.Button("Remove input variable") |
|
execute_btn = gr.Button("Execute") |
|
for t in all_tasks.values(): |
|
t.render() |
|
task_error = gr.HighlightedText( |
|
[("Repeated variable names in tasks. Please pick different names.", "Error")], |
|
show_label=False, |
|
visible=False, |
|
) |
|
with gr.Row(): |
|
add_task_btn = gr.Button("Add task") |
|
remove_task_btn = gr.Button("Remove task") |
|
|
|
|
|
add_input_btn.click( |
|
add_input, |
|
inputs=[], |
|
outputs=[i.gr_component for i in all_inputs.values()], |
|
) |
|
remove_input_btn.click( |
|
remove_input, |
|
inputs=[], |
|
outputs=[i.gr_component for i in all_inputs.values()], |
|
) |
|
add_task_btn.click( |
|
add_task, |
|
inputs=[], |
|
outputs=[t.gr_component for t in all_tasks.values()], |
|
) |
|
remove_task_btn.click( |
|
remove_task, |
|
inputs=[], |
|
outputs=[t.gr_component for t in all_tasks.values()], |
|
) |
|
|
|
demo.launch() |
|
|