lgaleana commited on
Commit
78dfff8
1 Parent(s): 5e9e416

Generalize tasks through their inputs

Browse files
Files changed (3) hide show
  1. actions.py +33 -15
  2. app.py +1 -1
  3. components.py +27 -6
actions.py CHANGED
@@ -2,7 +2,7 @@ import re
2
 
3
  import gradio as gr
4
 
5
- from components import AITask, all_inputs, all_tasks, Input, MAX_INPUTS, MAX_TASKS
6
 
7
 
8
  def add_input(*visibility):
@@ -59,19 +59,32 @@ def _clear_error():
59
  return gr.HighlightedText.update(value=None, visible=False)
60
 
61
 
62
- def execute_task(id_: int, prompt: str, prev_error_value, *vars):
63
- inputs = vars[:MAX_INPUTS]
64
- task_outputs = vars[MAX_INPUTS:]
65
-
66
- prompt_vars = set(re.findall("{(.*?)}", prompt))
67
- vars_in_scope = {
68
- f"{Input.vname}{i}": input_ for i, input_ in enumerate(inputs) if input_
 
 
 
 
 
 
 
 
 
 
69
  }
70
- vars_in_scope.update(
71
- {f"{AITask.vname}{i}": task for i, task in enumerate(task_outputs)}
72
  )
73
- undefined_vars = prompt_vars - vars_in_scope.keys()
 
74
 
 
 
75
  if len(undefined_vars) > 0:
76
  return None, gr.HighlightedText.update(
77
  value=[
@@ -86,7 +99,12 @@ def execute_task(id_: int, prompt: str, prev_error_value, *vars):
86
  value=prev_error_value, visible=prev_error_value is not None
87
  )
88
 
89
- if prompt:
90
- return all_tasks[id_].execute(prompt, vars_in_scope), error_update
91
-
92
- return None, error_update
 
 
 
 
 
 
2
 
3
  import gradio as gr
4
 
5
+ from components import all_inputs, all_tasks, Input, MAX_INPUTS, MAX_TASKS, Task
6
 
7
 
8
  def add_input(*visibility):
 
59
  return gr.HighlightedText.update(value=None, visible=False)
60
 
61
 
62
+ def execute_task(id_: int, prev_error_value, n_inputs, *vars_in_scope):
63
+ """
64
+ Params:
65
+ - id_: This will tell us which task to execute.
66
+ - prev_error_value: I carry around whether there is an error in the execution, to be displayed at the end.
67
+ - n_inputs: How many inputs does this task have?
68
+ - vars: All variables in scope. This can be a) task inputs, input varaibles or previous task outputs.
69
+ """
70
+ n_inputs = int(n_inputs)
71
+ task_inputs = vars_in_scope[:n_inputs]
72
+ input_vars = vars_in_scope[n_inputs:MAX_INPUTS]
73
+ task_outputs = vars_in_scope[MAX_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 = {
78
+ f"{Input.vname}{i}": input_ for i, input_ in enumerate(input_vars) if input_
79
  }
80
+ vars.update(
81
+ {f"{Task.vname}{i}": task for i, task in enumerate(task_outputs)}
82
  )
83
+ # Get all variables referenced within the task inputs
84
+ prompt_vars = {v for ti in non_empty_task_inputs for v in re.findall("{(.*?)}", ti)}
85
 
86
+ # If there is an undefined variable referenced, HighlightedText will signal the error.
87
+ undefined_vars = prompt_vars - vars.keys()
88
  if len(undefined_vars) > 0:
89
  return None, gr.HighlightedText.update(
90
  value=[
 
99
  value=prev_error_value, visible=prev_error_value is not None
100
  )
101
 
102
+ if non_empty_task_inputs:
103
+ # Execute the task logic
104
+ return (
105
+ all_tasks[id_].execute(*non_empty_task_inputs, vars),
106
+ error_update,
107
+ )
108
+ else:
109
+ # There is no actionf or this task.
110
+ return None, error_update
app.py CHANGED
@@ -64,7 +64,7 @@ with gr.Blocks() as demo:
64
  for i, task in all_tasks.items():
65
  execution_event = execution_event.then(
66
  a.execute_task,
67
- inputs=[task.component_id, task.prompt, error_message] + a._get_all_vars_up_to(i), # type: ignore
68
  outputs=[task.output, error_message],
69
  )
70
 
 
64
  for i, task in all_tasks.items():
65
  execution_event = execution_event.then(
66
  a.execute_task,
67
+ inputs=[task.component_id, error_message, task.n_inputs] + task.inputs() + a._get_all_vars_up_to(i), # type: ignore
68
  outputs=[task.output, error_message],
69
  )
70
 
components.py CHANGED
@@ -1,5 +1,5 @@
1
  from abc import ABC, abstractmethod
2
- from typing import Dict, Optional
3
 
4
  import gradio as gr
5
 
@@ -23,11 +23,11 @@ class Component(ABC):
23
 
24
  @abstractmethod
25
  def _render(self, id_: int, visible: bool):
26
- pass
27
 
28
  @abstractmethod
29
  def _execute(self):
30
- pass
31
 
32
  def render(self) -> None:
33
  self.component_id = gr.Number(value=self._id, visible=False)
@@ -35,7 +35,7 @@ class Component(ABC):
35
  self.gr_component = self._render(self._id, self._initial_visibility)
36
 
37
  def execute(self, *args):
38
- print(f"Executing component :: {self._source}.{self._id}")
39
  return self._execute(*args)
40
 
41
 
@@ -51,13 +51,31 @@ class Input(Component):
51
  )
52
  return self.output
53
 
54
- def _execute(self):
55
  pass
56
 
57
 
58
- class AITask(Component):
59
  vname = "t"
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  def _render(self, id_: int, visible: bool) -> gr.Box:
62
  with gr.Box(visible=visible) as gr_component:
63
  gr.Markdown(f"AI task")
@@ -80,6 +98,9 @@ class AITask(Component):
80
  formatted_prompt = prompt.format(**prompt_vars)
81
  return ai.llm.next([{"role": "user", "content": formatted_prompt}])
82
 
 
 
 
83
 
84
  MAX_INPUTS = 10
85
  MAX_TASKS = 10
 
1
  from abc import ABC, abstractmethod
2
+ from typing import Dict, List, Optional
3
 
4
  import gradio as gr
5
 
 
23
 
24
  @abstractmethod
25
  def _render(self, id_: int, visible: bool):
26
+ ...
27
 
28
  @abstractmethod
29
  def _execute(self):
30
+ ...
31
 
32
  def render(self) -> None:
33
  self.component_id = gr.Number(value=self._id, visible=False)
 
35
  self.gr_component = self._render(self._id, self._initial_visibility)
36
 
37
  def execute(self, *args):
38
+ print(f"Executing {self._source} :: {self._id}")
39
  return self._execute(*args)
40
 
41
 
 
51
  )
52
  return self.output
53
 
54
+ def _execute(self) -> None:
55
  pass
56
 
57
 
58
+ class Task(Component, ABC):
59
  vname = "t"
60
 
61
+ def __init__(self, id_: int, visible: bool = False):
62
+ super().__init__(id_, visible)
63
+ self.output: gr.Textbox
64
+
65
+ @abstractmethod
66
+ def inputs(self) -> List:
67
+ ...
68
+
69
+ @property
70
+ def _n_inputs(self) -> int:
71
+ return len(self.inputs())
72
+
73
+ def render(self) -> None:
74
+ super().render()
75
+ self.n_inputs = gr.Number(value=self._n_inputs, visible=False)
76
+
77
+
78
+ class AITask(Task):
79
  def _render(self, id_: int, visible: bool) -> gr.Box:
80
  with gr.Box(visible=visible) as gr_component:
81
  gr.Markdown(f"AI task")
 
98
  formatted_prompt = prompt.format(**prompt_vars)
99
  return ai.llm.next([{"role": "user", "content": formatted_prompt}])
100
 
101
+ def inputs(self) -> List[gr.Textbox]:
102
+ return [self.prompt]
103
+
104
 
105
  MAX_INPUTS = 10
106
  MAX_TASKS = 10