toolkit / components.py
lgaleana's picture
Fixed E2E
fb97b78
raw
history blame
4.93 kB
from abc import ABC, abstractmethod
from typing import List, Union
import gradio as gr
import requests
import ai
class Component(ABC):
def __init__(self, id_: int, visible: bool = False):
# Internal state
self._id = id_
self._source = self.__class__.__name__
self.vname: str
# Gradio state
self.component_id: gr.Number
self.gr_component: Union[gr.Box, gr.Textbox]
self.output: gr.Textbox
self.visible: gr.Number
def render(self) -> None:
self.component_id = gr.Number(value=self._id, visible=False)
self.visible = gr.Number(0, visible=False)
self.gr_component = self._render(self._id)
@abstractmethod
def _render(self, id_: int) -> Union[gr.Box, gr.Textbox]:
...
class Input(Component):
vname = "v"
def _render(self, id_: int) -> gr.Textbox:
self.output = gr.Textbox(
label=f"Input: {{{self.vname}{id_}}}",
interactive=True,
placeholder="Variable value",
visible=False,
)
return self.output
class TaskComponent(ABC):
vname = "t"
def __init__(self):
self.name: str
self.gr_component: gr.Box
self.input: gr.Textbox
self.output: gr.Textbox
self._source = self.__class__.__name__
def render(self, id_: int) -> None:
self.gr_component = self._render(id_)
@abstractmethod
def _render(self, id_) -> gr.Box:
...
@abstractmethod
def execute(self, input):
...
class AITask(TaskComponent):
name = "AI Task"
def _render(self, id_: int) -> gr.Box:
with gr.Box(visible=False) as gr_component:
gr.Markdown("Send a message to ChatGPT.")
with gr.Row():
self.input = gr.Textbox(
label="Prompt",
lines=10,
interactive=True,
placeholder="Example: summarize this text: {v0}",
)
self.output = gr.Textbox(
label=f"Output: {{{self.vname}{id_}}}",
lines=10,
interactive=False,
)
return gr_component
def execute(self, prompt: str) -> str:
return ai.llm.next([{"role": "user", "content": prompt}])
class VisitURL(TaskComponent):
name = "Visit URL"
def _render(self, id_: int) -> gr.Box:
with gr.Box(visible=False) as gr_component:
gr.Markdown("Get the content from an URL.")
with gr.Row():
self.input = gr.Textbox(
interactive=True,
placeholder="URL",
show_label=False,
)
self.output = gr.Textbox(
label=f"Output: {{{self.vname}{id_}}}",
lines=10,
interactive=False,
)
return gr_component
def execute(self, url: str) -> str:
return requests.get(url).text
class Task(Component):
available_tasks = [AITask, VisitURL]
vname = "t"
def __init__(self, id_: int, visible: bool = False):
super().__init__(id_, visible)
self._inner_tasks = [t() for t in self.available_tasks]
self.gr_component: gr.Box
def _render(self, id_: int) -> gr.Box:
with gr.Box(visible=False) as gr_component:
self.active_index = gr.Dropdown(
[AITask.name, VisitURL.name],
label="Pick a new Task",
type="index",
)
for t in self._inner_tasks:
t.render(id_)
self.active_index.select(
self.pick_task,
inputs=[self.active_index],
outputs=[t.gr_component for t in self._inner_tasks],
)
return gr_component
@staticmethod
def pick_task(idx):
update = [gr.Box.update(visible=False)] * len(Task.available_tasks)
update[idx] = gr.Box.update(visible=True)
return update
def inputs(self) -> List[gr.Textbox]:
return [t.input for t in self._inner_tasks]
def outputs(self) -> List[gr.Textbox]:
return [t.output for t in self._inner_tasks]
def execute(self, active_index, input):
inner_task = self._inner_tasks[active_index]
print(f"Executing {self._source}: {self._id}")
return inner_task.execute(input)
MAX_TASKS = 10
all_tasks = {i: Task(i) for i in range(MAX_TASKS)}
class Tasks:
@classmethod
def visibilities(cls) -> List[gr.Number]:
return [t.visible for t in all_tasks.values()]
@classmethod
def active_indexes(cls) -> List[gr.Dropdown]:
return [t.active_index for t in all_tasks.values()]
@classmethod
def gr_components(cls) -> List[gr.Box]:
return [t.gr_component for t in all_tasks.values()]