lgaleana commited on
Commit
71586bc
1 Parent(s): 45d6a3f

Implemented code task

Browse files
Files changed (3) hide show
  1. actions.py +35 -16
  2. app.py +3 -3
  3. components.py +52 -16
actions.py CHANGED
@@ -38,24 +38,40 @@ def execute_task(task_id: int, active_index: int, error_value, *args):
38
  - args: Other variables that will be decomposed.
39
  """
40
  n_avail_tasks = len(Task.available_tasks)
41
- error_update = gr.HighlightedText.update(
42
- value=error_value, visible=error_value is not None
43
- )
44
  # We need to return outputs for all tasks in the row.
45
  outputs = [""] * n_avail_tasks
46
 
47
  if active_index is None: # Active index could be 0 == not active_index
48
- return outputs + [error_update]
 
 
 
 
49
 
50
  task_id = int(task_id)
51
  active_index = int(active_index)
 
52
 
53
- task_input = args[:n_avail_tasks][active_index]
54
- prev_active_indexes = args[n_avail_tasks : n_avail_tasks + task_id]
55
- prev_task_outputs = args[n_avail_tasks + task_id :]
 
 
 
 
 
 
 
 
 
56
 
57
- if not task_input:
58
- return outputs + [error_update]
 
 
 
 
 
59
 
60
  vars_in_scope = {}
61
  for i, prev_active_index in enumerate(prev_active_indexes):
@@ -63,7 +79,7 @@ def execute_task(task_id: int, active_index: int, error_value, *args):
63
  i * n_avail_tasks + int(prev_active_index)
64
  ]
65
  # Get all variables referenced within the task input
66
- prompt_vars = re.findall("{(.*?)}", task_input)
67
 
68
  # If there is an undefined variable referenced, HighlightedText will signal the error.
69
  undefined_vars = prompt_vars - vars_in_scope.keys()
@@ -73,7 +89,7 @@ def execute_task(task_id: int, active_index: int, error_value, *args):
73
  gr.HighlightedText.update(
74
  value=[
75
  (
76
- f"The following variables are being used before being defined :: {undefined_vars}. Please check your tasks.",
77
  "ERROR",
78
  )
79
  ],
@@ -81,18 +97,21 @@ def execute_task(task_id: int, active_index: int, error_value, *args):
81
  )
82
  ]
83
 
84
- formatted_input = task_input.format(**vars_in_scope)
85
  try:
86
  # Task logic gets inserted into the right index
87
  outputs[active_index] = all_tasks[task_id].execute(
88
- active_index, formatted_input
89
  )
90
- return outputs + [error_update]
 
 
 
 
91
  except Exception as e:
92
- outputs[active_index] = "ERROR"
93
  return outputs + [
94
  gr.HighlightedText.update(
95
- value=[(str(e), "ERROR")],
96
  visible=True,
97
  )
98
  ]
 
38
  - args: Other variables that will be decomposed.
39
  """
40
  n_avail_tasks = len(Task.available_tasks)
 
 
 
41
  # We need to return outputs for all tasks in the row.
42
  outputs = [""] * n_avail_tasks
43
 
44
  if active_index is None: # Active index could be 0 == not active_index
45
+ return outputs + [
46
+ gr.HighlightedText.update(
47
+ value=error_value, visible=error_value is not None
48
+ )
49
+ ]
50
 
51
  task_id = int(task_id)
52
  active_index = int(active_index)
53
+ inner_n_inputs = all_tasks[task_id].inner_n_inputs
54
 
55
+ start_inputs = 0
56
+ end_inputs = 0
57
+ end_all_inputs = sum(inner_n_inputs)
58
+ for i, n in enumerate(inner_n_inputs):
59
+ if i == active_index:
60
+ end_inputs = start_inputs + n
61
+ break
62
+ start_inputs += n
63
+ task_inputs = args[start_inputs:end_inputs]
64
+ prev_active_indexes = args[end_all_inputs : end_all_inputs + task_id]
65
+ prev_task_outputs = args[end_all_inputs + task_id :]
66
+ non_empty_inputs = [i for i in task_inputs if i]
67
 
68
+ if len(non_empty_inputs) < len(task_inputs):
69
+ return outputs + [
70
+ gr.HighlightedText.update(
71
+ value=[(f"Missing inputs for Task: {task_id}", "ERROR")],
72
+ visible=True,
73
+ )
74
+ ]
75
 
76
  vars_in_scope = {}
77
  for i, prev_active_index in enumerate(prev_active_indexes):
 
79
  i * n_avail_tasks + int(prev_active_index)
80
  ]
81
  # Get all variables referenced within the task input
82
+ prompt_vars = [v for ti in non_empty_inputs for v in re.findall("{(.*?)}", ti)]
83
 
84
  # If there is an undefined variable referenced, HighlightedText will signal the error.
85
  undefined_vars = prompt_vars - vars_in_scope.keys()
 
89
  gr.HighlightedText.update(
90
  value=[
91
  (
92
+ f"The variables in Task :: {task_id} are being used before being defined :: {undefined_vars}. Please check your tasks.",
93
  "ERROR",
94
  )
95
  ],
 
97
  )
98
  ]
99
 
 
100
  try:
101
  # Task logic gets inserted into the right index
102
  outputs[active_index] = all_tasks[task_id].execute(
103
+ active_index, *non_empty_inputs, vars_in_scope=vars_in_scope
104
  )
105
+ return outputs + [
106
+ gr.HighlightedText.update(
107
+ value=error_value, visible=error_value is not None
108
+ )
109
+ ]
110
  except Exception as e:
111
+ raise e
112
  return outputs + [
113
  gr.HighlightedText.update(
114
+ value=[(f"Error in Task {task_id} :: {e}", "ERROR")],
115
  visible=True,
116
  )
117
  ]
app.py CHANGED
@@ -51,10 +51,10 @@ with gr.Blocks() as demo:
51
  execution_event = execution_event.then(
52
  a.execute_task,
53
  inputs=[task.component_id, task.active_index, error_message]
54
- + task.inputs()
55
  + [t.active_index for t in prev_tasks]
56
- + [o for t in prev_tasks for o in t.outputs()],
57
- outputs=task.outputs() + [error_message],
58
  )
59
  prev_tasks.append(task)
60
 
 
51
  execution_event = execution_event.then(
52
  a.execute_task,
53
  inputs=[task.component_id, task.active_index, error_message]
54
+ + task.inputs
55
  + [t.active_index for t in prev_tasks]
56
+ + [o for t in prev_tasks for o in t.outputs],
57
+ outputs=task.outputs + [error_message],
58
  )
59
  prev_tasks.append(task)
60
 
components.py CHANGED
@@ -1,6 +1,6 @@
1
  from abc import ABC, abstractmethod
2
  from concurrent.futures import ThreadPoolExecutor
3
- from typing import Dict, List, Union
4
 
5
  import gradio as gr
6
 
@@ -56,12 +56,21 @@ class TaskComponent(ABC):
56
  def render(self, id_: int) -> None:
57
  self.gr_component = self._render(id_)
58
 
 
 
 
 
 
 
 
 
 
59
  @abstractmethod
60
  def _render(self, id_) -> gr.Box:
61
  ...
62
 
63
  @abstractmethod
64
- def execute(self, input):
65
  ...
66
 
67
 
@@ -85,8 +94,13 @@ class AITask(TaskComponent):
85
  )
86
  return gr_component
87
 
88
- def execute(self, prompt: str) -> str:
89
- return ai.llm.next([{"role": "user", "content": prompt}])
 
 
 
 
 
90
 
91
 
92
  class CodeTask(TaskComponent):
@@ -119,9 +133,8 @@ class CodeTask(TaskComponent):
119
  error_message = gr.HighlightedText(value=None, visible=False)
120
 
121
  self.input = gr.Textbox(
 
122
  interactive=True,
123
- placeholder="Input to the code",
124
- show_label=False,
125
  )
126
  with gr.Column():
127
  self.output = gr.Textbox(
@@ -158,6 +171,7 @@ class CodeTask(TaskComponent):
158
  error_message,
159
  )
160
 
 
161
  try:
162
  raw_prompt_output = ai.llm.next(
163
  [
@@ -168,7 +182,7 @@ class CodeTask(TaskComponent):
168
  {code_prompt}
169
 
170
  Do't save anything to disk. Instead, the function should return the necessary data.
171
- Include all the necessary imports but put them inside the function itself.
172
  """,
173
  }
174
  ],
@@ -187,13 +201,13 @@ class CodeTask(TaskComponent):
187
  The following text should have a python function with some imports that might need to be installed:
188
  {raw_prompt_output}
189
 
190
- Extract all the python packages, nothing else. Print them in a single python list what can be used with eval().
191
  """,
192
  f"""
193
- The following text should have a python function:
194
  {raw_prompt_output}
195
 
196
- Exclusively extract the function, nothing else.
197
  """,
198
  ],
199
  )
@@ -209,15 +223,31 @@ class CodeTask(TaskComponent):
209
  error_message,
210
  )
211
 
212
- def execute(self, url: str) -> str:
213
- ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
 
215
 
216
  class Task(Component):
217
  available_tasks = [AITask, CodeTask]
218
  vname = "t"
219
 
220
- def __init__(self, id_: int, visible: bool = False):
221
  super().__init__(id_)
222
  self._inner_tasks = [t() for t in self.available_tasks]
223
  self.gr_component: gr.Box
@@ -245,16 +275,22 @@ class Task(Component):
245
  update[idx] = gr.Box.update(visible=True)
246
  return update
247
 
 
248
  def inputs(self) -> List[gr.Textbox]:
249
- return [t.input for t in self._inner_tasks]
250
 
 
251
  def outputs(self) -> List[gr.Textbox]:
252
  return [t.output for t in self._inner_tasks]
253
 
254
- def execute(self, active_index, input):
 
 
 
 
255
  inner_task = self._inner_tasks[active_index]
256
  print(f"Executing {self._source}: {self._id}")
257
- return inner_task.execute(input)
258
 
259
 
260
  MAX_TASKS = 10
 
1
  from abc import ABC, abstractmethod
2
  from concurrent.futures import ThreadPoolExecutor
3
+ from typing import Any, Dict, List, Union
4
 
5
  import gradio as gr
6
 
 
56
  def render(self, id_: int) -> None:
57
  self.gr_component = self._render(id_)
58
 
59
+ @property
60
+ @abstractmethod
61
+ def inputs(self) -> List[gr.Textbox]:
62
+ ...
63
+
64
+ @property
65
+ def n_inputs(self) -> int:
66
+ return len(self.inputs)
67
+
68
  @abstractmethod
69
  def _render(self, id_) -> gr.Box:
70
  ...
71
 
72
  @abstractmethod
73
+ def execute(self, *args, vars_in_scope: Dict[str, Any]):
74
  ...
75
 
76
 
 
94
  )
95
  return gr_component
96
 
97
+ @property
98
+ def inputs(self) -> List[gr.Textbox]:
99
+ return [self.input]
100
+
101
+ def execute(self, prompt: str, vars_in_scope: Dict[str, Any]) -> str:
102
+ formatted_prompt = prompt.format(**vars_in_scope)
103
+ return ai.llm.next([{"role": "user", "content": formatted_prompt}])
104
 
105
 
106
  class CodeTask(TaskComponent):
 
133
  error_message = gr.HighlightedText(value=None, visible=False)
134
 
135
  self.input = gr.Textbox(
136
+ label="Input to the code",
137
  interactive=True,
 
 
138
  )
139
  with gr.Column():
140
  self.output = gr.Textbox(
 
171
  error_message,
172
  )
173
 
174
+ print(f"Generating code.")
175
  try:
176
  raw_prompt_output = ai.llm.next(
177
  [
 
182
  {code_prompt}
183
 
184
  Do't save anything to disk. Instead, the function should return the necessary data.
185
+ Include all the necessary imports.
186
  """,
187
  }
188
  ],
 
201
  The following text should have a python function with some imports that might need to be installed:
202
  {raw_prompt_output}
203
 
204
+ Extract all the python packages, nothing else. Print them in a single python list that can be used with eval().
205
  """,
206
  f"""
207
+ The following text should have a python function and some imports:
208
  {raw_prompt_output}
209
 
210
+ Exclusively extract the function and the imports, nothing else, so that it can be used with exec().
211
  """,
212
  ],
213
  )
 
223
  error_message,
224
  )
225
 
226
+ @property
227
+ def inputs(self) -> List[gr.Textbox]:
228
+ return [self.packages, self.function, self.input]
229
+
230
+ def execute(
231
+ self, packages: str, function: str, input: str, vars_in_scope: Dict[str, Any]
232
+ ):
233
+ import subprocess
234
+ import sys
235
+
236
+ for p in eval(packages):
237
+ subprocess.check_call([sys.executable, "-m", "pip", "install", p])
238
+ __import__(p)
239
+ exec(function, locals())
240
+ self._toolkit_func = list(locals().items())[-1][1]
241
+
242
+ formatted_input = input.format(**vars_in_scope)
243
+ return self._toolkit_func(formatted_input)
244
 
245
 
246
  class Task(Component):
247
  available_tasks = [AITask, CodeTask]
248
  vname = "t"
249
 
250
+ def __init__(self, id_: int):
251
  super().__init__(id_)
252
  self._inner_tasks = [t() for t in self.available_tasks]
253
  self.gr_component: gr.Box
 
275
  update[idx] = gr.Box.update(visible=True)
276
  return update
277
 
278
+ @property
279
  def inputs(self) -> List[gr.Textbox]:
280
+ return [i for t in self._inner_tasks for i in t.inputs]
281
 
282
+ @property
283
  def outputs(self) -> List[gr.Textbox]:
284
  return [t.output for t in self._inner_tasks]
285
 
286
+ @property
287
+ def inner_n_inputs(self) -> List[int]:
288
+ return [t.n_inputs for t in self._inner_tasks]
289
+
290
+ def execute(self, active_index, *args, vars_in_scope: Dict[str, Any]):
291
  inner_task = self._inner_tasks[active_index]
292
  print(f"Executing {self._source}: {self._id}")
293
+ return inner_task.execute(*args, vars_in_scope)
294
 
295
 
296
  MAX_TASKS = 10