lgaleana commited on
Commit
c4df480
1 Parent(s): 0905f7c

Fix website

Browse files
Files changed (3) hide show
  1. actions.py +55 -41
  2. app.py +17 -14
  3. components.py +31 -65
actions.py CHANGED
@@ -3,7 +3,7 @@ from typing import List
3
 
4
  import gradio as gr
5
 
6
- from components import Input, State as s, Task
7
 
8
 
9
  def _is_task_row_fully_invisible(row: List[int]) -> bool:
@@ -17,7 +17,7 @@ def add_task(index, *visibility):
17
  visibility = list(visibility)
18
  n_avail_tasks = len(Task.available_tasks)
19
 
20
- for i in range(s.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]
@@ -25,21 +25,28 @@ def add_task(index, *visibility):
25
  if is_row_invisible:
26
  unchanged_up_to = start_row + index
27
  return (
28
- [gr.Box.update()] * unchanged_up_to
 
 
 
29
  + [gr.Box.update(visible=True)]
30
  + [gr.Box.update()] * (len(visibility) - unchanged_up_to - 1)
31
  + [gr.Number.update()] * unchanged_up_to
32
  + [1]
33
  + [gr.Number.update()] * (len(visibility) - unchanged_up_to - 1)
34
  )
35
- return [gr.Box.update()] * len(visibility) + [gr.Number.update()] * len(visibility)
 
 
 
 
36
 
37
 
38
  def remove_task(*visibility):
39
  visibility = list(visibility)
40
  n_avail_tasks = len(Task.available_tasks)
41
 
42
- for i in range(s.MAX_TASKS):
43
  start_row = i * n_avail_tasks
44
  is_row_invisible = _is_task_row_fully_invisible(
45
  visibility[start_row : start_row + n_avail_tasks]
@@ -60,48 +67,55 @@ def remove_task(*visibility):
60
  )
61
 
62
 
63
- def execute_task(id_: int, prev_error_value, n_task_inputs, *vars_in_scope):
64
  """
65
  Params:
66
- - id_: This will tell us which task to execute.
 
67
  - prev_error_value: I carry around whether there is an error in the execution, to be displayed at the end.
68
- - n_task_inputs: How many inputs does this task have?
69
- - vars_in_scope: All variables in scope. This can be a) input varaibles, b) task inputs or c) previous task outputs.
70
  """
71
- n_task_inputs = int(n_task_inputs)
72
- task_inputs = vars_in_scope[:n_task_inputs]
73
- task_outputs = vars_in_scope[n_task_inputs:]
74
- non_empty_task_inputs = [ti for ti in task_inputs if ti]
75
-
76
- # Put all defined variables into a dict, with names (except task inputs)
77
- vars.update(
78
- {f"{Task.vname}{i}": task_output for i, task_output in enumerate(task_outputs)}
 
 
79
  )
80
- # Get all variables referenced within the task inputs
81
- prompt_vars = {v for ti in non_empty_task_inputs for v in re.findall("{(.*?)}", ti)}
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  # If there is an undefined variable referenced, HighlightedText will signal the error.
84
- undefined_vars = prompt_vars - vars.keys()
85
  if len(undefined_vars) > 0:
86
- return None, gr.HighlightedText.update(
87
- value=[
88
- (
89
- f"The following variables are being used before being defined :: {undefined_vars}. Please check your tasks.",
90
- "ERROR",
91
- )
92
- ],
93
- visible=True,
94
- )
95
- error_update = gr.HighlightedText.update(
96
- value=prev_error_value, visible=prev_error_value is not None
97
- )
98
 
99
- if non_empty_task_inputs:
100
- # Execute the task logic
101
- return (
102
- s.all_tasks[id_].execute(*non_empty_task_inputs, vars),
103
- error_update,
104
- )
105
- else:
106
- # There is no actionf for this task.
107
- return None, error_update
 
3
 
4
  import gradio as gr
5
 
6
+ from components import MAX_TASKS, all_tasks, Task
7
 
8
 
9
  def _is_task_row_fully_invisible(row: List[int]) -> bool:
 
17
  visibility = list(visibility)
18
  n_avail_tasks = len(Task.available_tasks)
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]
 
25
  if is_row_invisible:
26
  unchanged_up_to = start_row + index
27
  return (
28
+ [gr.Number.update()] * i
29
+ + [index]
30
+ + [gr.Number.update()] * (MAX_TASKS - i - 1)
31
+ + [gr.Box.update()] * unchanged_up_to
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(*visibility):
46
  visibility = list(visibility)
47
  n_avail_tasks = len(Task.available_tasks)
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]
 
67
  )
68
 
69
 
70
+ def execute_task(task_id: int, active_index: int, error_value, *args):
71
  """
72
  Params:
73
+ - task_id: This will tell us which task to execute.
74
+ - active_index: The index of the actual task that is visible.
75
  - prev_error_value: I carry around whether there is an error in the execution, to be displayed at the end.
76
+ - args: Other variables that will be decomposed.
 
77
  """
78
+ task_id = int(task_id)
79
+ active_index = int(active_index)
80
+ n_avail_tasks = len(Task.available_tasks)
81
+
82
+ task_input = args[:n_avail_tasks][active_index]
83
+ prev_active_indexes = args[n_avail_tasks : n_avail_tasks + task_id]
84
+ prev_task_outputs = args[n_avail_tasks + task_id :]
85
+
86
+ error_update = gr.HighlightedText.update(
87
+ value=error_value, visible=error_value is not None
88
  )
89
+ # We need to return outputs for all tasks in the row.
90
+ outputs = [""] * n_avail_tasks
91
+
92
+ if not task_input:
93
+ return outputs + [error_update]
94
+
95
+ vars_in_scope = {}
96
+ for i, prev_active_index in enumerate(prev_active_indexes):
97
+ vars_in_scope[f"{Task.vname}{i}"] = prev_task_outputs[
98
+ i * n_avail_tasks + int(prev_active_index)
99
+ ]
100
+ # Get all variables referenced within the task input
101
+ prompt_vars = re.findall("{(.*?)}", task_input)
102
 
103
  # If there is an undefined variable referenced, HighlightedText will signal the error.
104
+ undefined_vars = prompt_vars - vars_in_scope.keys()
105
  if len(undefined_vars) > 0:
106
+ return outputs + [
107
+ gr.HighlightedText.update(
108
+ value=[
109
+ (
110
+ f"The following variables are being used before being defined :: {undefined_vars}. Please check your tasks.",
111
+ "ERROR",
112
+ )
113
+ ],
114
+ visible=True,
115
+ )
116
+ ]
 
117
 
118
+ formatted_input = task_input.format(**vars_in_scope)
119
+ # Task logic gets inserted into the right index
120
+ outputs[active_index] = all_tasks[task_id].execute(active_index, formatted_input)
121
+ return outputs + [error_update]
 
 
 
 
 
app.py CHANGED
@@ -1,11 +1,7 @@
1
  import gradio as gr
2
 
3
  import actions as a
4
- from components import AITask, State as s, VisitURL
5
-
6
-
7
- def _get_all_vars_up_to(to: int):
8
- return [t.output for i, t in s.all_tasks.items() if i < to]
9
 
10
 
11
  with gr.Blocks() as demo:
@@ -23,7 +19,7 @@ with gr.Blocks() as demo:
23
  <br>Example prompt: "Translate the following text into spanish and add {v0} more sentences: {t0}".
24
  """
25
  )
26
- for t in s.all_tasks.values():
27
  t.render()
28
  task_picker = gr.Dropdown(
29
  [AITask.name, VisitURL.name],
@@ -40,26 +36,33 @@ with gr.Blocks() as demo:
40
  # Edit layout
41
  add_task_btn.click(
42
  a.add_task,
43
- inputs=[task_picker] + s.task_visibilities(), # type: ignore
44
- outputs=s.task_rows(),
45
  )
46
  remove_task_btn.click(
47
- a.remove_task, inputs=s.task_visibilities(), outputs=s.task_rows()
 
 
48
  )
49
 
50
  # Sequential execution
51
  execution_event = execute_btn.click(
 
52
  lambda: gr.HighlightedText.update(value=None, visible=False),
53
  inputs=[],
54
  outputs=[error_message],
55
  )
56
- for i, task in s.all_tasks.items():
 
 
57
  execution_event = execution_event.then(
58
  a.execute_task,
59
- inputs=[task.component_id, error_message, task.n_inputs]
60
- + task.inputs
61
- + _get_all_vars_up_to(i),
62
- outputs=[task.output, error_message],
 
63
  )
 
64
 
65
  demo.launch()
 
1
  import gradio as gr
2
 
3
  import actions as a
4
+ from components import AITask, all_tasks, Tasks, VisitURL
 
 
 
 
5
 
6
 
7
  with gr.Blocks() as demo:
 
19
  <br>Example prompt: "Translate the following text into spanish and add {v0} more sentences: {t0}".
20
  """
21
  )
22
+ for t in all_tasks.values():
23
  t.render()
24
  task_picker = gr.Dropdown(
25
  [AITask.name, VisitURL.name],
 
36
  # Edit layout
37
  add_task_btn.click(
38
  a.add_task,
39
+ inputs=[task_picker] + Tasks.visibilities(),
40
+ outputs=Tasks.active_indexes() + Tasks.gr_components() + Tasks.visibilities(),
41
  )
42
  remove_task_btn.click(
43
+ a.remove_task,
44
+ inputs=Tasks.visibilities(),
45
+ outputs=Tasks.gr_components() + Tasks.visibilities(),
46
  )
47
 
48
  # Sequential execution
49
  execution_event = execute_btn.click(
50
+ # Clear error message
51
  lambda: gr.HighlightedText.update(value=None, visible=False),
52
  inputs=[],
53
  outputs=[error_message],
54
  )
55
+
56
+ prev_tasks = []
57
+ for i, task in all_tasks.items():
58
  execution_event = execution_event.then(
59
  a.execute_task,
60
+ inputs=[task.component_id, task.active_index, error_message]
61
+ + task.inputs()
62
+ + [t.active_index for t in prev_tasks]
63
+ + [o for t in prev_tasks for o in t.outputs()],
64
+ outputs=task.outputs() + [error_message],
65
  )
66
+ prev_tasks.append(task)
67
 
68
  demo.launch()
components.py CHANGED
@@ -1,5 +1,5 @@
1
  from abc import ABC, abstractmethod
2
- from typing import Dict, List, Optional, Tuple
3
 
4
  import gradio as gr
5
  import requests
@@ -48,20 +48,13 @@ class Input(Component):
48
  class TaskComponent(Component, ABC):
49
  vname = "t"
50
 
51
- @abstractmethod
52
- def inputs(self) -> List:
53
- ...
54
-
55
- @property
56
- def _n_inputs(self) -> int:
57
- return len(self.inputs())
58
-
59
- def render(self) -> None:
60
- super().render()
61
- self.n_inputs = gr.Number(value=self._n_inputs, visible=False)
62
 
63
  @abstractmethod
64
- def execute(self, *vars, vars_in_scope: Dict[str, str]):
65
  ...
66
 
67
 
@@ -77,7 +70,7 @@ class AITask(TaskComponent):
77
  """
78
  )
79
  with gr.Row():
80
- self.prompt = gr.Textbox(
81
  label="Instructions",
82
  lines=10,
83
  interactive=True,
@@ -90,14 +83,8 @@ class AITask(TaskComponent):
90
  )
91
  return gr_component
92
 
93
- def execute(self, prompt: str, vars_in_scope: Dict[str, str]) -> Optional[str]:
94
- if prompt:
95
- formatted_prompt = prompt.format(**vars_in_scope)
96
- print(f"Executing {self.name} with prompt :: {formatted_prompt}")
97
- return ai.llm.next([{"role": "user", "content": formatted_prompt}])
98
-
99
- def inputs(self) -> List[gr.Textbox]:
100
- return [self.prompt]
101
 
102
 
103
  class VisitURL(TaskComponent):
@@ -112,7 +99,7 @@ class VisitURL(TaskComponent):
112
  """
113
  )
114
  with gr.Row():
115
- self.url = gr.Textbox(
116
  interactive=True,
117
  placeholder="URL",
118
  show_label=False,
@@ -124,14 +111,8 @@ class VisitURL(TaskComponent):
124
  )
125
  return gr_component
126
 
127
- def execute(self, url: str, vars_in_scope: Dict[str, str]) -> Optional[str]:
128
- if url:
129
- formatted_url = url.format(**vars_in_scope)
130
- print(f"Executing {self.name} with url :: {formatted_url}")
131
- return requests.get(formatted_url).text
132
-
133
- def inputs(self) -> List[gr.Textbox]:
134
- return [self.url]
135
 
136
 
137
  class Task:
@@ -140,58 +121,43 @@ class Task:
140
 
141
  def __init__(self, id_: int):
142
  self._id = id_
143
- self._active_index = -1 # Nothing
144
  self._inner_tasks = [t(self._id, False) for t in self.available_tasks]
145
 
146
  def render(self) -> None:
147
- self.active_index = gr.Number(self._active_index, visible=False)
148
  for t in self._inner_tasks:
149
  t.render()
150
 
151
  @property
152
  def component_id(self) -> gr.Textbox:
153
- return self._inner_tasks[self._active_index].component_id
154
 
155
- @property
156
- def gr_component(self) -> gr.Box:
157
- return self._inner_tasks[self._active_index].gr_component
158
-
159
- @property
160
- def visible(self) -> gr.Number:
161
- return self._inner_tasks[self._active_index].visible
162
-
163
- @property
164
- def output(self) -> gr.Textbox:
165
- return self._inner_tasks[self._active_index].output
166
-
167
- @property
168
  def inputs(self) -> List[gr.Textbox]:
169
- return self._inner_tasks[self._active_index].inputs()
170
 
171
- @property
172
- def n_inputs(self) -> int:
173
- return self._inner_tasks[self._active_index].n_inputs
174
 
175
- def execute(self, *args):
176
- inner_task = self._inner_tasks[self._active_index]
177
  print(f"Executing {inner_task._source}: {inner_task._id}")
178
- return inner_task.execute(*args)
179
 
180
 
181
- class State:
182
- MAX_TASKS = 10
183
 
184
- all_tasks = {i: Task(i) for i in range(MAX_TASKS)}
185
 
186
- @classmethod
187
- def task_visibilities(cls) -> List:
188
- return [it.visible for t in cls.all_tasks.values() for it in t._inner_tasks]
189
 
 
190
  @classmethod
191
- def task_rows(cls) -> List:
192
- return [
193
- it.gr_component for t in cls.all_tasks.values() for it in t._inner_tasks
194
- ] + [it.visible for t in cls.all_tasks.values() for it in t._inner_tasks]
195
 
 
 
 
196
 
197
- tasks = State()
 
 
 
1
  from abc import ABC, abstractmethod
2
+ from typing import List
3
 
4
  import gradio as gr
5
  import requests
 
48
  class TaskComponent(Component, ABC):
49
  vname = "t"
50
 
51
+ def __init__(self, id_: int, visible: bool = False):
52
+ super().__init__(id_, visible)
53
+ self.name: str
54
+ self.input: gr.Textbox
 
 
 
 
 
 
 
55
 
56
  @abstractmethod
57
+ def execute(self, input):
58
  ...
59
 
60
 
 
70
  """
71
  )
72
  with gr.Row():
73
+ self.input = gr.Textbox(
74
  label="Instructions",
75
  lines=10,
76
  interactive=True,
 
83
  )
84
  return gr_component
85
 
86
+ def execute(self, prompt: str) -> str:
87
+ return ai.llm.next([{"role": "user", "content": prompt}])
 
 
 
 
 
 
88
 
89
 
90
  class VisitURL(TaskComponent):
 
99
  """
100
  )
101
  with gr.Row():
102
+ self.input = gr.Textbox(
103
  interactive=True,
104
  placeholder="URL",
105
  show_label=False,
 
111
  )
112
  return gr_component
113
 
114
+ def execute(self, url: str) -> str:
115
+ return requests.get(url).text
 
 
 
 
 
 
116
 
117
 
118
  class Task:
 
121
 
122
  def __init__(self, id_: int):
123
  self._id = id_
 
124
  self._inner_tasks = [t(self._id, False) for t in self.available_tasks]
125
 
126
  def render(self) -> None:
127
+ self.active_index = gr.Number(-1, visible=False)
128
  for t in self._inner_tasks:
129
  t.render()
130
 
131
  @property
132
  def component_id(self) -> gr.Textbox:
133
+ return self._inner_tasks[0].component_id
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  def inputs(self) -> List[gr.Textbox]:
136
+ return [t.input for t in self._inner_tasks]
137
 
138
+ def outputs(self) -> List[gr.Textbox]:
139
+ return [t.output for t in self._inner_tasks]
 
140
 
141
+ def execute(self, active_index, input):
142
+ inner_task = self._inner_tasks[active_index]
143
  print(f"Executing {inner_task._source}: {inner_task._id}")
144
+ return inner_task.execute(input)
145
 
146
 
147
+ MAX_TASKS = 10
 
148
 
149
+ all_tasks = {i: Task(i) for i in range(MAX_TASKS)}
150
 
 
 
 
151
 
152
+ class Tasks:
153
  @classmethod
154
+ def visibilities(cls) -> List[gr.Number]:
155
+ return [it.visible for t in all_tasks.values() for it in t._inner_tasks]
 
 
156
 
157
+ @classmethod
158
+ def active_indexes(cls) -> List[gr.Number]:
159
+ return [t.active_index for t in all_tasks.values()]
160
 
161
+ @classmethod
162
+ def gr_components(cls) -> List[gr.Box]:
163
+ return [it.gr_component for t in all_tasks.values() for it in t._inner_tasks]