Updated interface to pick tasks
Browse files- actions.py +16 -46
- app.py +3 -9
- components.py +63 -49
actions.py
CHANGED
@@ -13,58 +13,28 @@ def _is_task_row_fully_invisible(row: List[int]) -> bool:
|
|
13 |
return True
|
14 |
|
15 |
|
16 |
-
def add_task(
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
for i in range(MAX_TASKS):
|
21 |
-
start_row = i * n_avail_tasks
|
22 |
-
is_row_invisible = _is_task_row_fully_invisible(
|
23 |
-
visibility[start_row : start_row + n_avail_tasks]
|
24 |
-
)
|
25 |
-
if is_row_invisible:
|
26 |
-
unchanged_up_to = start_row + index
|
27 |
return (
|
28 |
-
[gr.
|
29 |
-
+ [
|
30 |
-
+ [
|
31 |
-
+ [
|
32 |
-
+ [gr.Box.update(visible=True)]
|
33 |
-
+ [gr.Box.update()] * (len(visibility) - unchanged_up_to - 1)
|
34 |
-
+ [gr.Number.update()] * unchanged_up_to
|
35 |
-
+ [1]
|
36 |
-
+ [gr.Number.update()] * (len(visibility) - unchanged_up_to - 1)
|
37 |
)
|
38 |
-
return (
|
39 |
-
[gr.Number.update()] * MAX_TASKS
|
40 |
-
+ [gr.Box.update()] * len(visibility)
|
41 |
-
+ [gr.Number.update()] * len(visibility)
|
42 |
-
)
|
43 |
|
44 |
|
45 |
-
def remove_task(*
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
for i in range(MAX_TASKS):
|
50 |
-
start_row = i * n_avail_tasks
|
51 |
-
is_row_invisible = _is_task_row_fully_invisible(
|
52 |
-
visibility[start_row : start_row + n_avail_tasks]
|
53 |
-
)
|
54 |
-
if is_row_invisible:
|
55 |
-
unchanged_up_to = start_row - n_avail_tasks
|
56 |
return (
|
57 |
-
[gr.Box.update()] *
|
58 |
-
+ [gr.Box.update(visible=False)] * (
|
59 |
-
+ [
|
60 |
-
+ [0] * (
|
61 |
)
|
62 |
-
return (
|
63 |
-
[gr.Box.update()] * (len(visibility) - n_avail_tasks)
|
64 |
-
+ [gr.Box.update(visible=False)] * n_avail_tasks
|
65 |
-
+ [gr.Number.update()] * (len(visibility) - n_avail_tasks)
|
66 |
-
+ [0] * (len(visibility) - n_avail_tasks)
|
67 |
-
)
|
68 |
|
69 |
|
70 |
def execute_task(task_id: int, active_index: int, error_value, *args):
|
|
|
13 |
return True
|
14 |
|
15 |
|
16 |
+
def add_task(*visibilities):
|
17 |
+
for i, visible in enumerate(visibilities, 1):
|
18 |
+
if not bool(visible):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
return (
|
20 |
+
[gr.Box.update(visible=True)] * i
|
21 |
+
+ [gr.Box.update(visible=False)] * (MAX_TASKS - i)
|
22 |
+
+ [1] * i
|
23 |
+
+ [0] * (MAX_TASKS - i)
|
|
|
|
|
|
|
|
|
|
|
24 |
)
|
25 |
+
return [gr.Box.update()] * MAX_TASKS + [gr.Number.update()] * MAX_TASKS
|
|
|
|
|
|
|
|
|
26 |
|
27 |
|
28 |
+
def remove_task(*visibilities):
|
29 |
+
for i, visible in reversed(list(enumerate(visibilities))):
|
30 |
+
if bool(visible):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
return (
|
32 |
+
[gr.Box.update(visible=True)] * i
|
33 |
+
+ [gr.Box.update(visible=False)] * (MAX_TASKS - i)
|
34 |
+
+ [1] * i
|
35 |
+
+ [0] * (MAX_TASKS - i)
|
36 |
)
|
37 |
+
return [gr.Box.update()] * MAX_TASKS + [gr.Number.update()] * MAX_TASKS
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
|
40 |
def execute_task(task_id: int, active_index: int, error_value, *args):
|
app.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import gradio as gr
|
2 |
|
3 |
import actions as a
|
4 |
-
from components import
|
5 |
|
6 |
|
7 |
with gr.Blocks() as demo:
|
@@ -21,12 +21,6 @@ with gr.Blocks() as demo:
|
|
21 |
)
|
22 |
for t in all_tasks.values():
|
23 |
t.render()
|
24 |
-
task_picker = gr.Dropdown(
|
25 |
-
[AITask.name, VisitURL.name],
|
26 |
-
value=AITask.name,
|
27 |
-
label="Pick a new Task",
|
28 |
-
type="index",
|
29 |
-
)
|
30 |
with gr.Row():
|
31 |
add_task_btn = gr.Button("Add task")
|
32 |
remove_task_btn = gr.Button("Remove task")
|
@@ -36,8 +30,8 @@ with gr.Blocks() as demo:
|
|
36 |
# Edit layout
|
37 |
add_task_btn.click(
|
38 |
a.add_task,
|
39 |
-
inputs=
|
40 |
-
outputs=Tasks.
|
41 |
)
|
42 |
remove_task_btn.click(
|
43 |
a.remove_task,
|
|
|
1 |
import gradio as gr
|
2 |
|
3 |
import actions as a
|
4 |
+
from components import all_tasks, Tasks
|
5 |
|
6 |
|
7 |
with gr.Blocks() as demo:
|
|
|
21 |
)
|
22 |
for t in all_tasks.values():
|
23 |
t.render()
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
with gr.Row():
|
25 |
add_task_btn = gr.Button("Add task")
|
26 |
remove_task_btn = gr.Button("Remove task")
|
|
|
30 |
# Edit layout
|
31 |
add_task_btn.click(
|
32 |
a.add_task,
|
33 |
+
inputs=Tasks.visibilities(),
|
34 |
+
outputs=Tasks.gr_components() + Tasks.visibilities(),
|
35 |
)
|
36 |
remove_task_btn.click(
|
37 |
a.remove_task,
|
components.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
from abc import ABC, abstractmethod
|
2 |
-
from typing import List
|
3 |
|
4 |
import gradio as gr
|
5 |
import requests
|
@@ -8,50 +8,57 @@ import ai
|
|
8 |
|
9 |
|
10 |
class Component(ABC):
|
11 |
-
vname = None
|
12 |
-
|
13 |
def __init__(self, id_: int, visible: bool = False):
|
14 |
# Internal state
|
15 |
self._id = id_
|
16 |
self._source = self.__class__.__name__
|
17 |
-
self.
|
18 |
|
19 |
# Gradio state
|
20 |
self.component_id: gr.Number
|
21 |
-
self.
|
22 |
-
self.gr_component = gr.Box
|
23 |
self.output: gr.Textbox
|
24 |
-
|
25 |
-
@abstractmethod
|
26 |
-
def _render(self, id_: int, visible: bool):
|
27 |
-
...
|
28 |
|
29 |
def render(self) -> None:
|
30 |
self.component_id = gr.Number(value=self._id, visible=False)
|
31 |
-
self.visible = gr.Number(
|
32 |
-
self.gr_component = self._render(self._id
|
|
|
|
|
|
|
|
|
33 |
|
34 |
|
35 |
class Input(Component):
|
36 |
vname = "v"
|
37 |
|
38 |
-
def _render(self, id_: int
|
39 |
self.output = gr.Textbox(
|
40 |
label=f"Input: {{{self.vname}{id_}}}",
|
41 |
interactive=True,
|
42 |
placeholder="Variable value",
|
43 |
-
visible=
|
44 |
)
|
45 |
return self.output
|
46 |
|
47 |
|
48 |
-
class TaskComponent(
|
49 |
vname = "t"
|
50 |
|
51 |
-
def __init__(self
|
52 |
-
super().__init__(id_, visible)
|
53 |
self.name: str
|
|
|
54 |
self.input: gr.Textbox
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
@abstractmethod
|
57 |
def execute(self, input):
|
@@ -61,20 +68,15 @@ class TaskComponent(Component, ABC):
|
|
61 |
class AITask(TaskComponent):
|
62 |
name = "AI Task"
|
63 |
|
64 |
-
def _render(self, id_: int
|
65 |
-
with gr.Box(
|
66 |
-
gr.Markdown(
|
67 |
-
f"""
|
68 |
-
{self.name}
|
69 |
-
<br> Use this Task to give instructions to ChatGPT.
|
70 |
-
"""
|
71 |
-
)
|
72 |
with gr.Row():
|
73 |
self.input = gr.Textbox(
|
74 |
label="Instructions",
|
75 |
lines=10,
|
76 |
interactive=True,
|
77 |
-
placeholder="Example
|
78 |
)
|
79 |
self.output = gr.Textbox(
|
80 |
label=f"Output: {{{self.vname}{id_}}}",
|
@@ -90,14 +92,9 @@ class AITask(TaskComponent):
|
|
90 |
class VisitURL(TaskComponent):
|
91 |
name = "Visit URL"
|
92 |
|
93 |
-
def _render(self, id_: int
|
94 |
-
with gr.Box(
|
95 |
-
gr.Markdown(
|
96 |
-
f"""
|
97 |
-
{self.name}
|
98 |
-
<br> Use this Task to visit an URL and get its content.
|
99 |
-
"""
|
100 |
-
)
|
101 |
with gr.Row():
|
102 |
self.input = gr.Textbox(
|
103 |
interactive=True,
|
@@ -109,28 +106,45 @@ class VisitURL(TaskComponent):
|
|
109 |
lines=10,
|
110 |
interactive=False,
|
111 |
)
|
112 |
-
|
113 |
|
114 |
def execute(self, url: str) -> str:
|
115 |
return requests.get(url).text
|
116 |
|
117 |
|
118 |
-
class Task:
|
119 |
available_tasks = [AITask, VisitURL]
|
120 |
vname = "t"
|
121 |
|
122 |
-
def __init__(self, id_: int):
|
123 |
-
|
124 |
-
self._inner_tasks = [t(
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
|
131 |
-
@
|
132 |
-
def
|
133 |
-
|
|
|
|
|
134 |
|
135 |
def inputs(self) -> List[gr.Textbox]:
|
136 |
return [t.input for t in self._inner_tasks]
|
@@ -152,7 +166,7 @@ all_tasks = {i: Task(i) for i in range(MAX_TASKS)}
|
|
152 |
class Tasks:
|
153 |
@classmethod
|
154 |
def visibilities(cls) -> List[gr.Number]:
|
155 |
-
return [
|
156 |
|
157 |
@classmethod
|
158 |
def active_indexes(cls) -> List[gr.Number]:
|
@@ -160,4 +174,4 @@ class Tasks:
|
|
160 |
|
161 |
@classmethod
|
162 |
def gr_components(cls) -> List[gr.Box]:
|
163 |
-
return [
|
|
|
1 |
from abc import ABC, abstractmethod
|
2 |
+
from typing import List, Union
|
3 |
|
4 |
import gradio as gr
|
5 |
import requests
|
|
|
8 |
|
9 |
|
10 |
class Component(ABC):
|
|
|
|
|
11 |
def __init__(self, id_: int, visible: bool = False):
|
12 |
# Internal state
|
13 |
self._id = id_
|
14 |
self._source = self.__class__.__name__
|
15 |
+
self.vname: str
|
16 |
|
17 |
# Gradio state
|
18 |
self.component_id: gr.Number
|
19 |
+
self.gr_component: Union[gr.Box, gr.Textbox]
|
|
|
20 |
self.output: gr.Textbox
|
21 |
+
self.visible: gr.Number
|
|
|
|
|
|
|
22 |
|
23 |
def render(self) -> None:
|
24 |
self.component_id = gr.Number(value=self._id, visible=False)
|
25 |
+
self.visible = gr.Number(0, visible=False)
|
26 |
+
self.gr_component = self._render(self._id)
|
27 |
+
|
28 |
+
@abstractmethod
|
29 |
+
def _render(self, id_: int) -> Union[gr.Box, gr.Textbox]:
|
30 |
+
...
|
31 |
|
32 |
|
33 |
class Input(Component):
|
34 |
vname = "v"
|
35 |
|
36 |
+
def _render(self, id_: int) -> gr.Textbox:
|
37 |
self.output = gr.Textbox(
|
38 |
label=f"Input: {{{self.vname}{id_}}}",
|
39 |
interactive=True,
|
40 |
placeholder="Variable value",
|
41 |
+
visible=False,
|
42 |
)
|
43 |
return self.output
|
44 |
|
45 |
|
46 |
+
class TaskComponent(ABC):
|
47 |
vname = "t"
|
48 |
|
49 |
+
def __init__(self):
|
|
|
50 |
self.name: str
|
51 |
+
self.gr_component: gr.Box
|
52 |
self.input: gr.Textbox
|
53 |
+
self.output: gr.Textbox
|
54 |
+
|
55 |
+
def render(self, id_: int) -> None:
|
56 |
+
self.gr_component = self._render(id_)
|
57 |
+
self.gr_component.visible = False
|
58 |
+
|
59 |
+
@abstractmethod
|
60 |
+
def _render(self, id_) -> gr.Box:
|
61 |
+
...
|
62 |
|
63 |
@abstractmethod
|
64 |
def execute(self, input):
|
|
|
68 |
class AITask(TaskComponent):
|
69 |
name = "AI Task"
|
70 |
|
71 |
+
def _render(self, id_: int) -> gr.Box:
|
72 |
+
with gr.Box() as gr_component:
|
73 |
+
gr.Markdown("Give instructions to ChatGPT to do something.")
|
|
|
|
|
|
|
|
|
|
|
74 |
with gr.Row():
|
75 |
self.input = gr.Textbox(
|
76 |
label="Instructions",
|
77 |
lines=10,
|
78 |
interactive=True,
|
79 |
+
placeholder="Example: summarize this text: {v0}",
|
80 |
)
|
81 |
self.output = gr.Textbox(
|
82 |
label=f"Output: {{{self.vname}{id_}}}",
|
|
|
92 |
class VisitURL(TaskComponent):
|
93 |
name = "Visit URL"
|
94 |
|
95 |
+
def _render(self, id_: int) -> gr.Box:
|
96 |
+
with gr.Box() as gr_component:
|
97 |
+
gr.Markdown("Visit an URL and get its content.")
|
|
|
|
|
|
|
|
|
|
|
98 |
with gr.Row():
|
99 |
self.input = gr.Textbox(
|
100 |
interactive=True,
|
|
|
106 |
lines=10,
|
107 |
interactive=False,
|
108 |
)
|
109 |
+
return gr_component
|
110 |
|
111 |
def execute(self, url: str) -> str:
|
112 |
return requests.get(url).text
|
113 |
|
114 |
|
115 |
+
class Task(Component):
|
116 |
available_tasks = [AITask, VisitURL]
|
117 |
vname = "t"
|
118 |
|
119 |
+
def __init__(self, id_: int, visible: bool = False):
|
120 |
+
super().__init__(id_, visible)
|
121 |
+
self._inner_tasks = [t() for t in self.available_tasks]
|
122 |
+
self.gr_component: gr.Box
|
123 |
+
|
124 |
+
def _render(self, id_: int) -> gr.Box:
|
125 |
+
with gr.Box(visible=False) as gr_component:
|
126 |
+
self.task_picker = gr.Dropdown(
|
127 |
+
[AITask.name, VisitURL.name],
|
128 |
+
value=AITask.name,
|
129 |
+
label="Pick a new Task",
|
130 |
+
type="index",
|
131 |
+
)
|
132 |
+
self.active_index = gr.Number(-1, visible=False)
|
133 |
+
for t in self._inner_tasks:
|
134 |
+
t.render(id_)
|
135 |
+
|
136 |
+
self.task_picker.select(
|
137 |
+
self.pick_task,
|
138 |
+
inputs=[self.task_picker],
|
139 |
+
outputs=[t.gr_component for t in self._inner_tasks],
|
140 |
+
)
|
141 |
+
return gr_component
|
142 |
|
143 |
+
@staticmethod
|
144 |
+
def pick_task(idx):
|
145 |
+
update = [gr.Box.update(visible=False)] * len(Task.available_tasks)
|
146 |
+
update[idx] = gr.Box.update(visible=True)
|
147 |
+
return update
|
148 |
|
149 |
def inputs(self) -> List[gr.Textbox]:
|
150 |
return [t.input for t in self._inner_tasks]
|
|
|
166 |
class Tasks:
|
167 |
@classmethod
|
168 |
def visibilities(cls) -> List[gr.Number]:
|
169 |
+
return [t.visible for t in all_tasks.values()]
|
170 |
|
171 |
@classmethod
|
172 |
def active_indexes(cls) -> List[gr.Number]:
|
|
|
174 |
|
175 |
@classmethod
|
176 |
def gr_components(cls) -> List[gr.Box]:
|
177 |
+
return [t.gr_component for t in all_tasks.values()]
|