david-oplatka commited on
Commit
684067e
·
1 Parent(s): 9cdc5d0

Add refs for rerendering components

Browse files
Files changed (5) hide show
  1. app.py +0 -1
  2. chatbox.py +108 -21
  3. chatui.py +9 -5
  4. footer.py +142 -6
  5. header.py +47 -37
app.py CHANGED
@@ -31,7 +31,6 @@ def App():
31
  set_agent_log_entries([])
32
 
33
  def add_log_entry(new_log_entry):
34
- print(f"ADDING LOG ENTRY {new_log_entry}")
35
  set_agent_log_entries(lambda previous_entries: previous_entries + [new_log_entry])
36
 
37
  return agent_log_entries, add_log_entry, reset_log_entries
 
31
  set_agent_log_entries([])
32
 
33
  def add_log_entry(new_log_entry):
 
34
  set_agent_log_entries(lambda previous_entries: previous_entries + [new_log_entry])
35
 
36
  return agent_log_entries, add_log_entry, reset_log_entries
chatbox.py CHANGED
@@ -2,15 +2,34 @@ from reactpy import component, html, svg
2
  from reactpy.core.hooks import use_ref
3
 
4
  @component
5
- # def ChatBox(message, set_message, handle_input_change, handle_key_down, send_message, collapsed):
6
  def ChatBox(message, set_message, send_message, collapsed):
7
-
 
8
  def handle_input_change(event):
 
9
  set_message(event['target']['value'])
10
-
11
  def handle_key_down(event):
 
12
  if event['key'] == 'Enter' and message.strip():
13
  send_message()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  return html.div(
16
  {
@@ -51,7 +70,7 @@ def ChatBox(message, set_message, send_message, collapsed):
51
  "position": "absolute",
52
  "right": "8px",
53
  "top": "50%",
54
- "transform":"translateY(-50%)",
55
  "background": "none",
56
  "border": "none",
57
  "cursor": "pointer",
@@ -61,21 +80,89 @@ def ChatBox(message, set_message, send_message, collapsed):
61
  "justifyContent": "center",
62
  }
63
  },
64
- svg.svg(
65
- {
66
- "xmlns": "http://www.w3.org/2000/svg",
67
- "width": "20",
68
- "height": "20",
69
- "fill": "none",
70
- "stroke": "currentColor",
71
- "stroke-linecap": "round",
72
- "stroke-linejoin": "round",
73
- "stroke-width": "2",
74
- "viewBox": "0 0 24 24",
75
- "class": "feather feather-send",
76
- },
77
- svg.path({"d": "M22 2 11 13"}),
78
- svg.path({"d": "M22 2 15 22 11 13 2 9z"})
79
- )
80
  )
81
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  from reactpy.core.hooks import use_ref
3
 
4
  @component
 
5
  def ChatBox(message, set_message, send_message, collapsed):
6
+ # Store the static SVG button in a ref so it doesn't re-render unnecessarily
7
+ send_button_ref = use_ref(None)
8
  def handle_input_change(event):
9
+ # Update the message state when input changes
10
  set_message(event['target']['value'])
 
11
  def handle_key_down(event):
12
+ # Check for Enter key and send message if the message is not empty
13
  if event['key'] == 'Enter' and message.strip():
14
  send_message()
15
+ # Only define the static button SVG once
16
+ if send_button_ref.current is None:
17
+ send_button_ref.current = svg.svg(
18
+ {
19
+ "xmlns": "http://www.w3.org/2000/svg",
20
+ "width": "20",
21
+ "height": "20",
22
+ "fill": "none",
23
+ "stroke": "currentColor",
24
+ "stroke-linecap": "round",
25
+ "stroke-linejoin": "round",
26
+ "stroke-width": "2",
27
+ "viewBox": "0 0 24 24",
28
+ "class": "feather feather-send",
29
+ },
30
+ svg.path({"d": "M22 2 11 13"}),
31
+ svg.path({"d": "M22 2 15 22 11 13 2 9z"})
32
+ )
33
 
34
  return html.div(
35
  {
 
70
  "position": "absolute",
71
  "right": "8px",
72
  "top": "50%",
73
+ "transform": "translateY(-50%)",
74
  "background": "none",
75
  "border": "none",
76
  "cursor": "pointer",
 
80
  "justifyContent": "center",
81
  }
82
  },
83
+ send_button_ref.current # Render the cached send button
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  )
85
+ )
86
+
87
+
88
+ # from reactpy import component, html, svg
89
+ # from reactpy.core.hooks import use_ref
90
+
91
+ # @component
92
+ # # def ChatBox(message, set_message, handle_input_change, handle_key_down, send_message, collapsed):
93
+ # def ChatBox(message, set_message, send_message, collapsed):
94
+
95
+ # def handle_input_change(event):
96
+ # set_message(event['target']['value'])
97
+
98
+ # def handle_key_down(event):
99
+ # if event['key'] == 'Enter' and message.strip():
100
+ # send_message()
101
+
102
+ # return html.div(
103
+ # {
104
+ # "style": {
105
+ # "position": "fixed",
106
+ # "bottom": "70px" if collapsed else "140px",
107
+ # "left": "50%",
108
+ # "transform": "translateX(-50%)",
109
+ # "width": "80%",
110
+ # "display": "flex",
111
+ # "alignItems": "center",
112
+ # "backgroundColor": "#FFFFFF",
113
+ # "borderRadius": "50px",
114
+ # "zIndex": "1000",
115
+ # }
116
+ # },
117
+ # html.input(
118
+ # {
119
+ # "type": "text",
120
+ # "value": message,
121
+ # "placeholder": "Your Message",
122
+ # "onChange": handle_input_change,
123
+ # "onKeyDown": handle_key_down,
124
+ # "style": {
125
+ # "width": "100%",
126
+ # "padding": "10px 50px 10px 20px",
127
+ # "border": "none",
128
+ # "borderRadius": "50px",
129
+ # "color": "#65558F",
130
+ # }
131
+ # }
132
+ # ),
133
+ # html.button(
134
+ # {
135
+ # "type": "button",
136
+ # "onClick": send_message,
137
+ # "style": {
138
+ # "position": "absolute",
139
+ # "right": "8px",
140
+ # "top": "50%",
141
+ # "transform":"translateY(-50%)",
142
+ # "background": "none",
143
+ # "border": "none",
144
+ # "cursor": "pointer",
145
+ # "padding": "8px",
146
+ # "display": "flex",
147
+ # "alignItems": "center",
148
+ # "justifyContent": "center",
149
+ # }
150
+ # },
151
+ # svg.svg(
152
+ # {
153
+ # "xmlns": "http://www.w3.org/2000/svg",
154
+ # "width": "20",
155
+ # "height": "20",
156
+ # "fill": "none",
157
+ # "stroke": "currentColor",
158
+ # "stroke-linecap": "round",
159
+ # "stroke-linejoin": "round",
160
+ # "stroke-width": "2",
161
+ # "viewBox": "0 0 24 24",
162
+ # "class": "feather feather-send",
163
+ # },
164
+ # svg.path({"d": "M22 2 11 13"}),
165
+ # svg.path({"d": "M22 2 15 22 11 13 2 9z"})
166
+ # )
167
+ # )
168
+ # )
chatui.py CHANGED
@@ -2,6 +2,7 @@ from markdown_it import MarkdownIt
2
  from mdit_py_plugins import front_matter
3
 
4
  from reactpy import component, html
 
5
 
6
  from utils import wait_message
7
 
@@ -51,8 +52,10 @@ def ExamplePrompts(examples, send_example, first_turn):
51
  question
52
  )
53
 
54
- if first_turn:
55
- return html.div(
 
 
56
  {
57
  "style": {
58
  "display": "flex",
@@ -86,6 +89,9 @@ def ExamplePrompts(examples, send_example, first_turn):
86
  *[create_prompt_button(q) for q in example_questions]
87
  )
88
  )
 
 
 
89
 
90
  return None
91
 
@@ -118,9 +124,7 @@ def ChatMessage(user, message):
118
 
119
  @component
120
  def Logs(messages, log_entries, show_logs, set_show_logs, show_logs_button):
121
- # print(f"DEBUG: LENGTH OF MESSAGES IS {len(messages)}")
122
- # print(f"DEBUG: LENGTH OF LOG MESSAGES IS {len(log_entries)}")
123
- # print(f"DEBUG: SHOW LOGS BUTTON IS {show_logs_button}")
124
  if (len(messages) > 0) and (len(log_entries) > 0) and (messages[-1]["message"] != wait_message) and (show_logs_button):
125
  if not show_logs:
126
  return html.div(
 
2
  from mdit_py_plugins import front_matter
3
 
4
  from reactpy import component, html
5
+ from reactpy.core.hooks import use_ref
6
 
7
  from utils import wait_message
8
 
 
52
  question
53
  )
54
 
55
+ examples_ref = use_ref(None)
56
+
57
+ if examples_ref.current is None:
58
+ examples_ref.current = html.div(
59
  {
60
  "style": {
61
  "display": "flex",
 
89
  *[create_prompt_button(q) for q in example_questions]
90
  )
91
  )
92
+
93
+ if first_turn:
94
+ return examples_ref.current
95
 
96
  return None
97
 
 
124
 
125
  @component
126
  def Logs(messages, log_entries, show_logs, set_show_logs, show_logs_button):
127
+
 
 
128
  if (len(messages) > 0) and (len(log_entries) > 0) and (messages[-1]["message"] != wait_message) and (show_logs_button):
129
  if not show_logs:
130
  return html.div(
footer.py CHANGED
@@ -1,10 +1,14 @@
1
- from reactpy import component, html, svg, hooks
 
2
 
3
  @component
4
  def Footer(collapsed, set_collapsed):
5
 
6
- if collapsed:
7
- return html.footer(
 
 
 
8
  {
9
  "style": {
10
  "backgroundColor": "#FFFFFF",
@@ -44,8 +48,9 @@ def Footer(collapsed, set_collapsed):
44
  )
45
  )
46
  )
47
- else:
48
- return html.footer(
 
49
  {
50
  "style": {
51
  "backgroundColor": "#FFFFFF",
@@ -119,4 +124,135 @@ def Footer(collapsed, set_collapsed):
119
  "It demonstrates the use of Agentic-RAG functionality with Vectara",
120
  )
121
  )
122
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from reactpy import component, html, svg, hooks
2
+ from reactpy.core.hooks import use_ref
3
 
4
  @component
5
  def Footer(collapsed, set_collapsed):
6
 
7
+ expanded_footer_ref = use_ref(None)
8
+ collapsed_footer_ref = use_ref(None)
9
+
10
+ if expanded_footer_ref.current is None:
11
+ expanded_footer_ref.current = html.footer(
12
  {
13
  "style": {
14
  "backgroundColor": "#FFFFFF",
 
48
  )
49
  )
50
  )
51
+
52
+ if collapsed_footer_ref.current is None:
53
+ collapsed_footer_ref.current = html.footer(
54
  {
55
  "style": {
56
  "backgroundColor": "#FFFFFF",
 
124
  "It demonstrates the use of Agentic-RAG functionality with Vectara",
125
  )
126
  )
127
+ )
128
+
129
+ if collapsed:
130
+ return expanded_footer_ref.current
131
+ else:
132
+ return collapsed_footer_ref.current
133
+
134
+
135
+
136
+
137
+ # from reactpy import component, html, svg, hooks
138
+
139
+ # @component
140
+ # def Footer(collapsed, set_collapsed):
141
+
142
+ # if collapsed:
143
+ # return html.footer(
144
+ # {
145
+ # "style": {
146
+ # "backgroundColor": "#FFFFFF",
147
+ # "position": "fixed",
148
+ # "bottom": 0,
149
+ # "width": "100%",
150
+ # "height": "50px",
151
+ # }
152
+ # },
153
+ # html.button(
154
+ # {
155
+ # "style": {
156
+ # "background": "none",
157
+ # "border": "none",
158
+ # "color": "#757575",
159
+ # "cursor": "pointer",
160
+ # "position": "absolute",
161
+ # "bottom": "5px",
162
+ # "right": "10px",
163
+ # },
164
+ # "type": "button",
165
+ # "on_click": lambda _: set_collapsed(False)
166
+ # },
167
+ # svg.svg(
168
+ # {
169
+ # "xmlns": "http://www.w3.org/2000/svg",
170
+ # "width": "24",
171
+ # "height": "24",
172
+ # "fill": "none",
173
+ # "stroke": "currentColor",
174
+ # "stroke-linecap": "round",
175
+ # "stroke-linejoin": "round",
176
+ # "stroke-width": "3",
177
+ # "viewBox": "0 0 24 24",
178
+ # },
179
+ # svg.path({"d": "M19 14l-7-7-7 7"})
180
+ # )
181
+ # )
182
+ # )
183
+ # else:
184
+ # return html.footer(
185
+ # {
186
+ # "style": {
187
+ # "backgroundColor": "#FFFFFF",
188
+ # "position": "fixed",
189
+ # "bottom": 0,
190
+ # "width": "100%",
191
+ # }
192
+ # },
193
+ # html.div(
194
+ # {
195
+ # "style": {
196
+ # "backgroundColor": "#FFFFFF",
197
+ # "padding": "0px 20px 0px 50px",
198
+ # "position": "relative",
199
+ # "display": "block",
200
+ # }
201
+ # },
202
+ # html.button(
203
+ # {
204
+ # "style": {
205
+ # "position": "absolute",
206
+ # "right": "10px",
207
+ # "background": "none",
208
+ # "border": "none",
209
+ # "color": "#757575",
210
+ # "cursor": "pointer",
211
+ # },
212
+ # "type": "button",
213
+ # "on_click": lambda _: set_collapsed(True)
214
+ # },
215
+ # svg.svg(
216
+ # {
217
+ # "xmlns": "http://www.w3.org/2000/svg",
218
+ # "width": "24",
219
+ # "height": "24",
220
+ # "fill": "none",
221
+ # "stroke": "currentColor",
222
+ # "stroke-linecap": "round",
223
+ # "stroke-linejoin": "round",
224
+ # "stroke-width": "3",
225
+ # "viewBox": "0 0 24 24",
226
+ # },
227
+ # svg.path({"d": "M18 6L6 18"}),
228
+ # svg.path({"d": "M6 6l12 12"})
229
+ # )
230
+ # ),
231
+ # html.p(
232
+ # {
233
+ # "style": {
234
+ # "fontSize": "20px",
235
+ # "color": "#4b4851"
236
+ # }
237
+ # },
238
+ # "How this works?",
239
+ # ),
240
+ # html.p(
241
+ # {
242
+ # "style": {
243
+ # "color": "#757575",
244
+ # }
245
+ # },
246
+ # "This app was built with ",
247
+ # html.a(
248
+ # {
249
+ # "href": "https://vectara.com/",
250
+ # "target": "_blank",
251
+ # },
252
+ # "Vectara",
253
+ # ),
254
+ # html.br(),
255
+ # "It demonstrates the use of Agentic-RAG functionality with Vectara",
256
+ # )
257
+ # )
258
+ # )
header.py CHANGED
@@ -1,4 +1,5 @@
1
  from reactpy import component, html, svg, hooks
 
2
 
3
  @component
4
  def Header(demo_name: str, short_description: str, extra_info: str, start_over):
@@ -7,16 +8,11 @@ def Header(demo_name: str, short_description: str, extra_info: str, start_over):
7
  def toggle_header(event=None):
8
  set_more_info(not more_info)
9
 
10
- return html.header(
11
- {
12
- "style": {
13
- "backgroundColor": "#FFFFFF",
14
- "display": "flex",
15
- "justifyContent": "space-between",
16
- "alignItems": "center",
17
- }
18
- },
19
- html.div(
20
  {
21
  "style": {
22
  "display": "flex",
@@ -46,7 +42,46 @@ def Header(demo_name: str, short_description: str, extra_info: str, start_over):
46
  },
47
  f"{demo_name}"
48
  ),
49
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  html.div(
51
  {
52
  "style": {
@@ -123,30 +158,5 @@ def Header(demo_name: str, short_description: str, extra_info: str, start_over):
123
  )
124
  )
125
  ),
126
- html.div(
127
- {
128
- "style": {
129
- "flex": 2,
130
- "textAlign": "right",
131
- "padding": "10px",
132
- }
133
- },
134
- html.button(
135
- {
136
- "style": {
137
- "backgroundColor": "#FFFFFF",
138
- "color": "#757575",
139
- "fontSize": "14px",
140
- "cursor": "pointer",
141
- "border": "1px solid #e2dfdf",
142
- "borderRadius": "5px",
143
- "padding": "6px 20px",
144
- "marginRight": "15px",
145
- },
146
- "type": "button",
147
- "onClick": start_over,
148
- },
149
- "Start Over?"
150
- )
151
- )
152
  )
 
1
  from reactpy import component, html, svg, hooks
2
+ from reactpy.core.hooks import use_ref
3
 
4
  @component
5
  def Header(demo_name: str, short_description: str, extra_info: str, start_over):
 
8
  def toggle_header(event=None):
9
  set_more_info(not more_info)
10
 
11
+ logo_section_ref = use_ref(None)
12
+ start_over_ref = use_ref(None)
13
+
14
+ if logo_section_ref.current is None:
15
+ logo_section_ref.current = html.div(
 
 
 
 
 
16
  {
17
  "style": {
18
  "display": "flex",
 
42
  },
43
  f"{demo_name}"
44
  ),
45
+ )
46
+
47
+ if start_over_ref.current is None:
48
+ start_over_ref.current = html.div(
49
+ {
50
+ "style": {
51
+ "flex": 2,
52
+ "textAlign": "right",
53
+ "padding": "10px",
54
+ }
55
+ },
56
+ html.button(
57
+ {
58
+ "style": {
59
+ "backgroundColor": "#FFFFFF",
60
+ "color": "#757575",
61
+ "fontSize": "14px",
62
+ "cursor": "pointer",
63
+ "border": "1px solid #e2dfdf",
64
+ "borderRadius": "5px",
65
+ "padding": "6px 20px",
66
+ "marginRight": "15px",
67
+ },
68
+ "type": "button",
69
+ "onClick": start_over,
70
+ },
71
+ "Start Over?"
72
+ )
73
+ )
74
+
75
+ return html.header(
76
+ {
77
+ "style": {
78
+ "backgroundColor": "#FFFFFF",
79
+ "display": "flex",
80
+ "justifyContent": "space-between",
81
+ "alignItems": "center",
82
+ }
83
+ },
84
+ logo_section_ref.current,
85
  html.div(
86
  {
87
  "style": {
 
158
  )
159
  )
160
  ),
161
+ start_over_ref.current
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  )