lgaleana commited on
Commit
a35fa4d
1 Parent(s): 169710f
Files changed (3) hide show
  1. actions.py +92 -0
  2. app.py +9 -176
  3. components.py +83 -0
actions.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 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):
9
+ for i, visible in enumerate(visibility, 1):
10
+ if not bool(visible):
11
+ return (
12
+ [gr.Textbox.update(visible=True)] * i
13
+ + [gr.Textbox.update(visible=False, value="")] * (MAX_INPUTS - i)
14
+ + [1] * i
15
+ + [0] * (MAX_INPUTS - i)
16
+ )
17
+
18
+
19
+ def remove_input(*visibility):
20
+ for i, visible in reversed(list(enumerate(visibility, 1))):
21
+ if bool(visible):
22
+ return (
23
+ [gr.Textbox.update(visible=True)] * (i - 1)
24
+ + [gr.Textbox.update(visible=False, value="")] * (MAX_INPUTS - i + 1)
25
+ + [1] * (i - 1)
26
+ + [0] * (MAX_INPUTS - i + 1)
27
+ )
28
+
29
+
30
+ def add_task(*visibility):
31
+ for i, visible in enumerate(visibility, 1):
32
+ if not bool(visible):
33
+ return (
34
+ [gr.Box.update(visible=True)] * i
35
+ + [gr.Box.update(visible=False)] * (MAX_TASKS - i)
36
+ + [1] * i
37
+ + [0] * (MAX_TASKS - i)
38
+ )
39
+
40
+
41
+ def remove_task(*visibility):
42
+ for i, visible in reversed(list(enumerate(visibility, 1))):
43
+ if bool(visible):
44
+ return (
45
+ [gr.Box.update(visible=True)] * (i - 1)
46
+ + [gr.Box.update(visible=False)] * (MAX_TASKS - i + 1)
47
+ + [1] * (i - 1)
48
+ + [0] * (MAX_TASKS - i + 1)
49
+ )
50
+
51
+
52
+ def _get_all_vars_up_to(to: int):
53
+ return [in_.output for in_ in all_inputs.values()] + [
54
+ t.output for i, t in all_tasks.items() if i < to
55
+ ]
56
+
57
+
58
+ 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=[
78
+ (
79
+ f"The following variables are being used before being defined :: {undefined_vars}. Please check your tasks.",
80
+ "ERROR",
81
+ )
82
+ ],
83
+ visible=True,
84
+ )
85
+ error_update = gr.HighlightedText.update(
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
app.py CHANGED
@@ -1,174 +1,7 @@
1
- import re
2
- from typing import Dict, Optional, Union
3
-
4
  import gradio as gr
5
 
6
- import ai
7
-
8
-
9
- MAX_INPUTS = 10
10
- MAX_TASKS = 10
11
-
12
-
13
- class Input:
14
- vname = "v"
15
-
16
- def render(self, id_: int, visible: bool) -> gr.Textbox:
17
- self.output = gr.Textbox(
18
- label=f"Input: {{{self.vname}{id_}}}",
19
- interactive=True,
20
- placeholder="Variable value",
21
- visible=visible,
22
- )
23
- return self.output
24
-
25
- def execute(self) -> None:
26
- pass
27
-
28
-
29
- class AITask:
30
- vname = "t"
31
-
32
- def render(self, id_: int, visible: bool) -> gr.Box:
33
- with gr.Box(visible=visible) as gr_component:
34
- gr.Markdown(f"AI task")
35
- with gr.Row():
36
- self.prompt = gr.Textbox(
37
- label="Instructions",
38
- lines=10,
39
- interactive=True,
40
- placeholder="What is the AI assistant meant to do?",
41
- )
42
- self.output = gr.Textbox(
43
- label=f"Output: {{{self.vname}{id_}}}",
44
- lines=10,
45
- interactive=False,
46
- )
47
- return gr_component
48
-
49
- def execute(self, prompt: str, prompt_vars: Dict[str, str]) -> Optional[str]:
50
- if prompt:
51
- formatted_prompt = prompt.format(**prompt_vars)
52
- return ai.llm.next([{"role": "user", "content": formatted_prompt}])
53
-
54
-
55
- class Component:
56
- def __init__(self, id_: int, internal: Union[Input, AITask], visible: bool = False):
57
- # Internal state
58
- self._id = id_
59
- self.internal = internal
60
- self._source = self.internal.__class__.__name__
61
- self._initial_visibility = visible
62
-
63
- # Gradio state
64
- self.component_id: gr.Number
65
- self.visible: gr.Number
66
- self.gr_component = gr.Box
67
- self.output: gr.Textbox
68
-
69
- def render(self) -> None:
70
- self.component_id = gr.Number(value=self._id, visible=False)
71
- self.visible = gr.Number(int(self._initial_visibility), visible=False)
72
- self.gr_component = self.internal.render(self._id, self._initial_visibility)
73
- self.output = self.internal.output
74
-
75
- def execute(self, *args):
76
- print(f"Executing component :: {self._source}.{self._id}")
77
- return self.internal.execute(*args)
78
-
79
-
80
- all_inputs = {i: Component(i, Input()) for i in range(MAX_INPUTS)}
81
- all_tasks = {i: Component(i, AITask()) for i in range(MAX_TASKS)}
82
-
83
- all_inputs[0]._initial_visibility = True
84
- all_tasks[0]._initial_visibility = True
85
-
86
-
87
- def _get_all_vars_up_to(to: int):
88
- return [in_.output for in_ in all_inputs.values()] + [
89
- t.output for i, t in all_tasks.items() if i < to
90
- ]
91
-
92
-
93
- def add_input(*visibility):
94
- for i, visible in enumerate(visibility, 1):
95
- if not bool(visible):
96
- return (
97
- [gr.Textbox.update(visible=True)] * i
98
- + [gr.Textbox.update(visible=False, value="")] * (MAX_INPUTS - i)
99
- + [1] * i
100
- + [0] * (MAX_INPUTS - i)
101
- )
102
-
103
-
104
- def remove_input(*visibility):
105
- for i, visible in reversed(list(enumerate(visibility, 1))):
106
- if bool(visible):
107
- return (
108
- [gr.Textbox.update(visible=True)] * (i - 1)
109
- + [gr.Textbox.update(visible=False, value="")] * (MAX_INPUTS - i + 1)
110
- + [1] * (i - 1)
111
- + [0] * (MAX_INPUTS - i + 1)
112
- )
113
-
114
-
115
- def add_task(*visibility):
116
- for i, visible in enumerate(visibility, 1):
117
- if not bool(visible):
118
- return (
119
- [gr.Box.update(visible=True)] * i
120
- + [gr.Box.update(visible=False)] * (MAX_TASKS - i)
121
- + [1] * i
122
- + [0] * (MAX_TASKS - i)
123
- )
124
-
125
-
126
- def remove_task(*visibility):
127
- for i, visible in reversed(list(enumerate(visibility, 1))):
128
- if bool(visible):
129
- return (
130
- [gr.Box.update(visible=True)] * (i - 1)
131
- + [gr.Box.update(visible=False)] * (MAX_TASKS - i + 1)
132
- + [1] * (i - 1)
133
- + [0] * (MAX_TASKS - i + 1)
134
- )
135
-
136
-
137
- def _clear_error():
138
- return gr.HighlightedText.update(value=None, visible=False)
139
-
140
-
141
- def execute_task(id_: int, prompt: str, prev_error_value, *vars):
142
- inputs = vars[:MAX_INPUTS]
143
- task_outputs = vars[MAX_INPUTS:]
144
-
145
- prompt_vars = set(re.findall("{(.*?)}", prompt))
146
- vars_in_scope = {
147
- f"{Input.vname}{i}": input_ for i, input_ in enumerate(inputs) if input_
148
- }
149
- vars_in_scope.update(
150
- {f"{AITask.vname}{i}": task for i, task in enumerate(task_outputs)}
151
- )
152
- undefined_vars = prompt_vars - vars_in_scope.keys()
153
-
154
- if len(undefined_vars) > 0:
155
- return None, gr.HighlightedText.update(
156
- value=[
157
- (
158
- f"The following variables are being used before being defined :: {undefined_vars}. Please check your tasks.",
159
- "ERROR",
160
- )
161
- ],
162
- visible=True,
163
- )
164
- error_update = gr.HighlightedText.update(
165
- value=prev_error_value, visible=prev_error_value is not None
166
- )
167
-
168
- if prompt:
169
- return all_tasks[id_].execute(prompt, vars_in_scope), error_update
170
-
171
- return None, error_update
172
 
173
 
174
  with gr.Blocks() as demo:
@@ -200,25 +33,25 @@ with gr.Blocks() as demo:
200
 
201
  # Edit layout
202
  add_input_btn.click(
203
- add_input,
204
  inputs=[i.visible for i in all_inputs.values()],
205
  outputs=[i.gr_component for i in all_inputs.values()] # type: ignore
206
  + [i.visible for i in all_inputs.values()],
207
  )
208
  remove_input_btn.click(
209
- remove_input,
210
  inputs=[i.visible for i in all_inputs.values()],
211
  outputs=[i.gr_component for i in all_inputs.values()] # type: ignore
212
  + [i.visible for i in all_inputs.values()],
213
  )
214
  add_task_btn.click(
215
- add_task,
216
  inputs=[i.visible for i in all_tasks.values()],
217
  outputs=[i.gr_component for i in all_tasks.values()] # type: ignore
218
  + [i.visible for i in all_tasks.values()],
219
  )
220
  remove_task_btn.click(
221
- remove_task,
222
  inputs=[i.visible for i in all_tasks.values()],
223
  outputs=[i.gr_component for i in all_tasks.values()] # type: ignore
224
  + [i.visible for i in all_tasks.values()],
@@ -226,12 +59,12 @@ with gr.Blocks() as demo:
226
 
227
  # Sequential execution
228
  execution_event = execute_btn.click(
229
- _clear_error, inputs=[], outputs=[error_message]
230
  )
231
  for i, task in all_tasks.items():
232
  execution_event = execution_event.then(
233
- execute_task,
234
- inputs=[task.component_id, task.internal.prompt, error_message] + _get_all_vars_up_to(i), # type: ignore
235
  outputs=[task.output, error_message],
236
  )
237
 
 
 
 
 
1
  import gradio as gr
2
 
3
+ import actions as a
4
+ from components import all_inputs, all_tasks
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
 
7
  with gr.Blocks() as demo:
 
33
 
34
  # Edit layout
35
  add_input_btn.click(
36
+ a.add_input,
37
  inputs=[i.visible for i in all_inputs.values()],
38
  outputs=[i.gr_component for i in all_inputs.values()] # type: ignore
39
  + [i.visible for i in all_inputs.values()],
40
  )
41
  remove_input_btn.click(
42
+ a.remove_input,
43
  inputs=[i.visible for i in all_inputs.values()],
44
  outputs=[i.gr_component for i in all_inputs.values()] # type: ignore
45
  + [i.visible for i in all_inputs.values()],
46
  )
47
  add_task_btn.click(
48
+ a.add_task,
49
  inputs=[i.visible for i in all_tasks.values()],
50
  outputs=[i.gr_component for i in all_tasks.values()] # type: ignore
51
  + [i.visible for i in all_tasks.values()],
52
  )
53
  remove_task_btn.click(
54
+ a.remove_task,
55
  inputs=[i.visible for i in all_tasks.values()],
56
  outputs=[i.gr_component for i in all_tasks.values()] # type: ignore
57
  + [i.visible for i in all_tasks.values()],
 
59
 
60
  # Sequential execution
61
  execution_event = execute_btn.click(
62
+ a._clear_error, inputs=[], outputs=[error_message]
63
  )
64
  for i, task in all_tasks.items():
65
  execution_event = execution_event.then(
66
+ a.execute_task,
67
+ inputs=[task.component_id, task.internal.prompt, error_message] + a._get_all_vars_up_to(i), # type: ignore
68
  outputs=[task.output, error_message],
69
  )
70
 
components.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, Optional, Union
2
+
3
+ import gradio as gr
4
+
5
+ import ai
6
+
7
+
8
+ class Input:
9
+ vname = "v"
10
+
11
+ def render(self, id_: int, visible: bool) -> gr.Textbox:
12
+ self.output = gr.Textbox(
13
+ label=f"Input: {{{self.vname}{id_}}}",
14
+ interactive=True,
15
+ placeholder="Variable value",
16
+ visible=visible,
17
+ )
18
+ return self.output
19
+
20
+ def execute(self) -> None:
21
+ pass
22
+
23
+
24
+ class AITask:
25
+ vname = "t"
26
+
27
+ def render(self, id_: int, visible: bool) -> gr.Box:
28
+ with gr.Box(visible=visible) as gr_component:
29
+ gr.Markdown(f"AI task")
30
+ with gr.Row():
31
+ self.prompt = gr.Textbox(
32
+ label="Instructions",
33
+ lines=10,
34
+ interactive=True,
35
+ placeholder="What is the AI assistant meant to do?",
36
+ )
37
+ self.output = gr.Textbox(
38
+ label=f"Output: {{{self.vname}{id_}}}",
39
+ lines=10,
40
+ interactive=False,
41
+ )
42
+ return gr_component
43
+
44
+ def execute(self, prompt: str, prompt_vars: Dict[str, str]) -> Optional[str]:
45
+ if prompt:
46
+ formatted_prompt = prompt.format(**prompt_vars)
47
+ return ai.llm.next([{"role": "user", "content": formatted_prompt}])
48
+
49
+
50
+ class Component:
51
+ def __init__(self, id_: int, internal: Union[Input, AITask], visible: bool = False):
52
+ # Internal state
53
+ self._id = id_
54
+ self.internal = internal
55
+ self._source = self.internal.__class__.__name__
56
+ self._initial_visibility = visible
57
+
58
+ # Gradio state
59
+ self.component_id: gr.Number
60
+ self.visible: gr.Number
61
+ self.gr_component = gr.Box
62
+ self.output: gr.Textbox
63
+
64
+ def render(self) -> None:
65
+ self.component_id = gr.Number(value=self._id, visible=False)
66
+ self.visible = gr.Number(int(self._initial_visibility), visible=False)
67
+ self.gr_component = self.internal.render(self._id, self._initial_visibility)
68
+ self.output = self.internal.output
69
+
70
+ def execute(self, *args):
71
+ print(f"Executing component :: {self._source}.{self._id}")
72
+ return self.internal.execute(*args)
73
+
74
+
75
+ MAX_INPUTS = 10
76
+ MAX_TASKS = 10
77
+
78
+
79
+ all_inputs = {i: Component(i, Input()) for i in range(MAX_INPUTS)}
80
+ all_tasks = {i: Component(i, AITask()) for i in range(MAX_TASKS)}
81
+
82
+ all_inputs[0]._initial_visibility = True
83
+ all_tasks[0]._initial_visibility = True