|
from typing import NamedTuple, Type, Union |
|
|
|
|
|
import gradio as gr |
|
|
|
|
|
MAX_INPUTS = 10 |
|
MAX_TASKS = 50 |
|
|
|
|
|
class Input: |
|
def render(self, visible: bool) -> gr.Box: |
|
with gr.Box(visible=visible) as gr_component: |
|
with gr.Row(): |
|
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: |
|
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.component_id: gr.Textbox |
|
self._internal = internal |
|
self.gr_component = gr.Box |
|
self.visible = visible |
|
self.output_name: gr.Textbox |
|
self.output: gr.Textbox |
|
self.source: 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(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 = [Component(i, Input()) for i in range(MAX_INPUTS)] |
|
all_tasks = [Component(i, AITask()) for i in range(MAX_TASKS)] |
|
all_components = all_inputs + all_tasks |
|
all_variables = {} |
|
|
|
all_inputs[0].visible = True |
|
all_tasks[0].visible = True |
|
next_input = 1 |
|
next_task = 1 |
|
|
|
|
|
def _update_components(i: int, max: int): |
|
return [gr.Box.update(visible=True)] * i + [gr.Box.update(visible=False)] * ( |
|
max - i |
|
) |
|
|
|
|
|
def add_input(): |
|
global next_input |
|
if next_input < MAX_INPUTS: |
|
next_input += 1 |
|
return _update_components(next_input, MAX_INPUTS) |
|
|
|
|
|
def remove_input(): |
|
global next_input |
|
if next_input > 0: |
|
next_input -= 1 |
|
return _update_components(next_input, MAX_INPUTS) |
|
|
|
|
|
def add_task(): |
|
global next_task |
|
if next_task < MAX_TASKS: |
|
next_task += 1 |
|
return _update_components(next_task, MAX_TASKS) |
|
|
|
|
|
def remove_task(): |
|
global next_task |
|
if next_task > 0: |
|
next_task -= 1 |
|
return _update_components(next_task, MAX_TASKS) |
|
|
|
|
|
def execute(output_names, outputs): |
|
for output_name in output_names: |
|
print(output_name) |
|
|
|
|
|
def update_scope_variables(component_id, source, output_name, output): |
|
all_variables[f"{source}.{component_id}"] = Variable( |
|
component_id, source, output_name, output |
|
) |
|
print(all_variables) |
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
|
for i in all_inputs: |
|
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: |
|
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], |
|
) |
|
remove_input_btn.click( |
|
remove_input, |
|
inputs=[], |
|
outputs=[i.gr_component for i in all_inputs], |
|
) |
|
add_task_btn.click( |
|
add_task, |
|
inputs=[], |
|
outputs=[t.gr_component for t in all_tasks], |
|
) |
|
remove_task_btn.click( |
|
remove_task, |
|
inputs=[], |
|
outputs=[t.gr_component for t in all_tasks], |
|
) |
|
|
|
|
|
for c in all_components: |
|
c.output_name.change( |
|
update_scope_variables, |
|
inputs=[c.component_id, c.source, c.output_name, c.output], |
|
outputs=[], |
|
) |
|
|
|
demo.launch() |
|
|