Richard commited on
Commit
b470e8d
·
1 Parent(s): 56bc33d

Add "add new row" and run prompt for empty response outputs.

Browse files
components/__init__.py CHANGED
@@ -7,3 +7,4 @@ from components.header import header as header
7
  from components.header import header_section as header_section
8
  from components.sidebar import icon_sidebar as icon_sidebar
9
  from components.sidebar import icon_menu_item as icon_menu_item
 
 
7
  from components.header import header_section as header_section
8
  from components.sidebar import icon_sidebar as icon_sidebar
9
  from components.sidebar import icon_menu_item as icon_menu_item
10
+ from components.snackbar import snackbar as snackbar
components/snackbar.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Callable, Literal
2
+
3
+ import mesop as me
4
+
5
+
6
+ @me.component
7
+ def snackbar(
8
+ *,
9
+ is_visible: bool,
10
+ label: str,
11
+ action_label: str | None = None,
12
+ on_click_action: Callable | None = None,
13
+ horizontal_position: Literal["start", "center", "end"] = "center",
14
+ vertical_position: Literal["start", "center", "end"] = "end",
15
+ ):
16
+ """Creates a snackbar.
17
+
18
+ By default the snackbar is rendered at bottom center.
19
+
20
+ The on_click_action should typically close the snackbar as part of its actions. If no
21
+ click event is included, you'll need to manually hide the snackbar.
22
+
23
+ Note that there is one issue with this snackbar example. No actions are possible until
24
+ the snackbar is dismissed or closed. This is due to the fixed box that gets created when
25
+ the snackbar is visible.
26
+
27
+ Args:
28
+ is_visible: Whether the snackbar is currently visible or not.
29
+ label: Message for the snackbar
30
+ action_label: Optional message for the action of the snackbar
31
+ on_click_action: Optional click event when action is triggered.
32
+ horizontal_position: Horizontal position of the snackbar
33
+ vertical_position: Vertical position of the snackbar
34
+ """
35
+ with me.box(
36
+ style=me.Style(
37
+ display="block" if is_visible else "none",
38
+ height="100%",
39
+ overflow_x="auto",
40
+ overflow_y="auto",
41
+ position="fixed",
42
+ width="100%",
43
+ z_index=1000,
44
+ )
45
+ ):
46
+ with me.box(
47
+ style=me.Style(
48
+ align_items=vertical_position,
49
+ height="100%",
50
+ display="flex",
51
+ justify_content=horizontal_position,
52
+ )
53
+ ):
54
+ with me.box(
55
+ style=me.Style(
56
+ align_items="center",
57
+ background="#2f3033",
58
+ border_radius=5,
59
+ box_shadow=("0 3px 1px -2px #0003, 0 2px 2px #00000024, 0 1px 5px #0000001f"),
60
+ display="flex",
61
+ font_size=14,
62
+ justify_content="space-between",
63
+ margin=me.Margin.all(10),
64
+ padding=me.Padding(top=5, bottom=5, right=5, left=15)
65
+ if action_label
66
+ else me.Padding.all(15),
67
+ width=300,
68
+ )
69
+ ):
70
+ me.text(label, style=me.Style(color="#fcfcfc"))
71
+ if action_label:
72
+ me.button(
73
+ action_label,
74
+ on_click=on_click_action,
75
+ style=me.Style(color="#d6e3fe"),
76
+ )
dialogs/__init__.py CHANGED
@@ -5,3 +5,4 @@ from dialogs.prompt_version_history import prompt_version_history as prompt_vers
5
  from dialogs.add_comparisons import add_comparisons as add_comparisons
6
  from dialogs.generate_prompt import generate_prompt as generate_prompt
7
  from dialogs.load_prompt import load_prompt as load_prompt
 
 
5
  from dialogs.add_comparisons import add_comparisons as add_comparisons
6
  from dialogs.generate_prompt import generate_prompt as generate_prompt
7
  from dialogs.load_prompt import load_prompt as load_prompt
8
+ from dialogs.add_row import add_row as add_row
dialogs/add_comparisons.py CHANGED
@@ -25,7 +25,12 @@ def add_comparisons():
25
  on_selection_change=on_select_comparison,
26
  )
27
  with mex.dialog_actions():
28
- me.button("Close", key="dialog_show_add_comparison", on_click=handlers.on_close_dialog)
 
 
 
 
 
29
 
30
 
31
  def on_select_comparison(e: me.SelectSelectionChangeEvent):
 
25
  on_selection_change=on_select_comparison,
26
  )
27
  with mex.dialog_actions():
28
+ me.button(
29
+ "Close",
30
+ key="dialog_show_add_comparison",
31
+ on_click=handlers.on_close_dialog,
32
+ style=me.Style(border_radius="10"),
33
+ )
34
 
35
 
36
  def on_select_comparison(e: me.SelectSelectionChangeEvent):
dialogs/add_row.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import copy
2
+
3
+ import mesop as me
4
+
5
+ import components as mex
6
+ import handlers
7
+ import llm
8
+ from constants import DIALOG_INPUT_WIDTH
9
+ from helpers import parse_variables, find_prompt
10
+ from state import State
11
+
12
+
13
+ @me.component
14
+ def add_row():
15
+ state = me.state(State)
16
+
17
+ with mex.dialog(state.dialog_show_add_row):
18
+ me.text("Add row", type="headline-6")
19
+ if not state.prompt_variables:
20
+ me.text("No variables defined in prompt.", style=me.Style(width=DIALOG_INPUT_WIDTH))
21
+ else:
22
+ with me.box(
23
+ style=me.Style(display="flex", justify_content="end", margin=me.Margin(bottom=15))
24
+ ):
25
+ me.button(
26
+ "Generate",
27
+ on_click=on_click_generate_variables,
28
+ style=me.Style(background="#EBF1FD", border_radius="10"),
29
+ )
30
+ variable_names = set(parse_variables(state.prompt))
31
+ with me.box(style=me.Style(display="flex", flex_direction="column")):
32
+ for name in state.prompt_variables.keys():
33
+ if name not in variable_names:
34
+ continue
35
+ me.textarea(
36
+ label=name,
37
+ value=state.add_row_prompt_variables.get(name, ""),
38
+ on_blur=on_input_variable,
39
+ style=me.Style(width=DIALOG_INPUT_WIDTH),
40
+ key=name,
41
+ )
42
+
43
+ with mex.dialog_actions():
44
+ me.button(
45
+ "Close",
46
+ on_click=on_close_dialog,
47
+ key="dialog_show_add_row",
48
+ style=me.Style(border_radius="10"),
49
+ )
50
+ me.button("Add", type="flat", on_click=on_click_add_row, style=me.Style(border_radius="10"))
51
+
52
+
53
+ def on_close_dialog(e: me.ClickEvent):
54
+ state = me.state(State)
55
+ state.add_row_prompt_variables = {}
56
+ handlers.on_close_dialog(e)
57
+
58
+
59
+ def on_click_add_row(e: me.ClickEvent):
60
+ state = me.state(State)
61
+ prompt = find_prompt(state.prompts, state.version)
62
+ prompt.responses.append(
63
+ {
64
+ "variables": copy.copy(state.add_row_prompt_variables),
65
+ "output": "",
66
+ "rating": 0,
67
+ }
68
+ )
69
+ state.add_row_prompt_variables = {}
70
+ state.dialog_show_add_row = False
71
+
72
+
73
+ def on_input_variable(e: me.InputBlurEvent):
74
+ """Generic event to save input variables."""
75
+ state = me.state(State)
76
+ state.add_row_prompt_variables[e.key] = e.value
77
+
78
+
79
+ def on_click_generate_variables(e: me.ClickEvent):
80
+ """Generates values for the given empty variables."""
81
+ state = me.state(State)
82
+ variable_names = set(parse_variables(state.prompt))
83
+ generated_variables = llm.generate_variables(
84
+ state.prompt, variable_names, state.model, state.model_temperature
85
+ )
86
+
87
+ for name in state.prompt_variables:
88
+ if name in variable_names and name in generated_variables:
89
+ state.add_row_prompt_variables[name] = generated_variables[name]
dialogs/generate_prompt.py CHANGED
@@ -21,8 +21,18 @@ def generate_prompt():
21
  style=me.Style(width=DIALOG_INPUT_WIDTH),
22
  )
23
  with mex.dialog_actions():
24
- me.button("Close", key="dialog_show_generate_prompt", on_click=handlers.on_close_dialog)
25
- me.button("Generate", type="flat", on_click=on_click_generate_prompt)
 
 
 
 
 
 
 
 
 
 
26
 
27
 
28
  def on_click_generate_prompt(e: me.ClickEvent):
 
21
  style=me.Style(width=DIALOG_INPUT_WIDTH),
22
  )
23
  with mex.dialog_actions():
24
+ me.button(
25
+ "Close",
26
+ key="dialog_show_generate_prompt",
27
+ on_click=handlers.on_close_dialog,
28
+ style=me.Style(border_radius="10"),
29
+ )
30
+ me.button(
31
+ "Generate",
32
+ type="flat",
33
+ on_click=on_click_generate_prompt,
34
+ style=me.Style(border_radius="10"),
35
+ )
36
 
37
 
38
  def on_click_generate_prompt(e: me.ClickEvent):
dialogs/load_prompt.py CHANGED
@@ -21,10 +21,15 @@ def load_prompt():
21
  type="flat",
22
  color="primary",
23
  on_upload=on_upload_prompt,
24
- style=me.Style(font_weight="bold"),
25
  )
26
  with mex.dialog_actions():
27
- me.button("Close", key="dialog_show_load", on_click=handlers.on_close_dialog)
 
 
 
 
 
28
 
29
 
30
  def on_upload_prompt(e: me.UploadEvent):
 
21
  type="flat",
22
  color="primary",
23
  on_upload=on_upload_prompt,
24
+ style=me.Style(font_weight="bold", border_radius=10),
25
  )
26
  with mex.dialog_actions():
27
+ me.button(
28
+ "Close",
29
+ key="dialog_show_load",
30
+ on_click=handlers.on_close_dialog,
31
+ style=me.Style(border_radius="10"),
32
+ )
33
 
34
 
35
  def on_upload_prompt(e: me.UploadEvent):
dialogs/model_settings.py CHANGED
@@ -47,6 +47,7 @@ def model_settings():
47
  "Close",
48
  key="dialog_show_model_settings",
49
  on_click=handlers.on_close_dialog,
 
50
  )
51
 
52
 
 
47
  "Close",
48
  key="dialog_show_model_settings",
49
  on_click=handlers.on_close_dialog,
50
+ style=me.Style(border_radius="10"),
51
  )
52
 
53
 
dialogs/prompt_variables.py CHANGED
@@ -20,7 +20,11 @@ def prompt_variables():
20
  with me.box(
21
  style=me.Style(display="flex", justify_content="end", margin=me.Margin(bottom=15))
22
  ):
23
- me.button("Generate", type="flat", on_click=on_click_generate_variables)
 
 
 
 
24
  variable_names = set(parse_variables(state.prompt))
25
  with me.box(style=me.Style(display="flex", flex_direction="column")):
26
  for name, value in state.prompt_variables.items():
@@ -35,7 +39,12 @@ def prompt_variables():
35
  )
36
 
37
  with mex.dialog_actions():
38
- me.button("Close", on_click=handlers.on_close_dialog, key="dialog_show_prompt_variables")
 
 
 
 
 
39
 
40
 
41
  def on_input_variable(e: me.InputBlurEvent):
@@ -50,7 +59,6 @@ def on_input_variable(e: me.InputBlurEvent):
50
  def on_click_generate_variables(e: me.ClickEvent):
51
  """Generates values for the given empty variables."""
52
  state = me.state(State)
53
- print(state.model)
54
  variable_names = set(parse_variables(state.prompt))
55
  generated_variables = llm.generate_variables(
56
  state.prompt, variable_names, state.model, state.model_temperature
 
20
  with me.box(
21
  style=me.Style(display="flex", justify_content="end", margin=me.Margin(bottom=15))
22
  ):
23
+ me.button(
24
+ "Generate",
25
+ on_click=on_click_generate_variables,
26
+ style=me.Style(background="#EBF1FD", border_radius="10"),
27
+ )
28
  variable_names = set(parse_variables(state.prompt))
29
  with me.box(style=me.Style(display="flex", flex_direction="column")):
30
  for name, value in state.prompt_variables.items():
 
39
  )
40
 
41
  with mex.dialog_actions():
42
+ me.button(
43
+ "Close",
44
+ on_click=handlers.on_close_dialog,
45
+ key="dialog_show_prompt_variables",
46
+ style=me.Style(border_radius="10"),
47
+ )
48
 
49
 
50
  def on_input_variable(e: me.InputBlurEvent):
 
59
  def on_click_generate_variables(e: me.ClickEvent):
60
  """Generates values for the given empty variables."""
61
  state = me.state(State)
 
62
  variable_names = set(parse_variables(state.prompt))
63
  generated_variables = llm.generate_variables(
64
  state.prompt, variable_names, state.model, state.model_temperature
dialogs/prompt_version_history.py CHANGED
@@ -23,7 +23,12 @@ def prompt_version_history():
23
  on_selection_change=on_select_version,
24
  )
25
  with mex.dialog_actions():
26
- me.button("Close", key="dialog_show_version_history", on_click=handlers.on_close_dialog)
 
 
 
 
 
27
 
28
 
29
  def on_select_version(e: me.SelectSelectionChangeEvent):
 
23
  on_selection_change=on_select_version,
24
  )
25
  with mex.dialog_actions():
26
+ me.button(
27
+ "Close",
28
+ key="dialog_show_version_history",
29
+ on_click=handlers.on_close_dialog,
30
+ style=me.Style(border_radius="10"),
31
+ )
32
 
33
 
34
  def on_select_version(e: me.SelectSelectionChangeEvent):
dialogs/update_title.py CHANGED
@@ -19,8 +19,19 @@ def update_title():
19
  style=me.Style(width=DIALOG_INPUT_WIDTH),
20
  )
21
  with mex.dialog_actions():
22
- me.button("Cancel", on_click=handlers.on_close_dialog, key="dialog_show_title")
23
- me.button("Save", type="flat", disabled=not state.temp_title.strip(), on_click=on_save_title)
 
 
 
 
 
 
 
 
 
 
 
24
 
25
 
26
  def on_save_title(e: me.InputBlurEvent):
 
19
  style=me.Style(width=DIALOG_INPUT_WIDTH),
20
  )
21
  with mex.dialog_actions():
22
+ me.button(
23
+ "Cancel",
24
+ on_click=handlers.on_close_dialog,
25
+ key="dialog_show_title",
26
+ style=me.Style(border_radius="10"),
27
+ )
28
+ me.button(
29
+ "Save",
30
+ type="flat",
31
+ disabled=not state.temp_title.strip(),
32
+ on_click=on_save_title,
33
+ style=me.Style(border_radius="10"),
34
+ )
35
 
36
 
37
  def on_save_title(e: me.InputBlurEvent):
eval_table.py CHANGED
@@ -7,7 +7,11 @@ from state import Prompt
7
 
8
 
9
  @me.component
10
- def prompt_eval_table(prompts: list[Prompt], on_select_rating: Callable | None = None):
 
 
 
 
11
  data = _make_table_meta(prompts)
12
  response_map = _make_response_map(prompts)
13
 
@@ -51,16 +55,31 @@ def prompt_eval_table(prompts: list[Prompt], on_select_rating: Callable | None =
51
  elif row["type"] == "model_response":
52
  with me.box(style=_MARKDOWN_BOX_STYLE):
53
  prompt_response = response_map[row["prompt"].version].get(response_key)
54
- if prompt_response:
55
  me.markdown(prompt_response[0]["output"])
56
  else:
57
- me.text("")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  elif row["type"] == "model_rating":
59
  with me.box(style=_RATING_STYLE):
60
  prompt_response = response_map[row["prompt"].version].get(response_key)
61
- if prompt_response:
62
  me.select(
63
- value=prompt_response[0].get("rating", ""),
64
  options=[
65
  me.SelectOption(label="1", value="1"),
66
  me.SelectOption(label="2", value="2"),
 
7
 
8
 
9
  @me.component
10
+ def prompt_eval_table(
11
+ prompts: list[Prompt],
12
+ on_select_rating: Callable | None = None,
13
+ on_click_run: Callable | None = None,
14
+ ):
15
  data = _make_table_meta(prompts)
16
  response_map = _make_response_map(prompts)
17
 
 
55
  elif row["type"] == "model_response":
56
  with me.box(style=_MARKDOWN_BOX_STYLE):
57
  prompt_response = response_map[row["prompt"].version].get(response_key)
58
+ if prompt_response and prompt_response[0]["output"]:
59
  me.markdown(prompt_response[0]["output"])
60
  else:
61
+ with me.box(
62
+ style=me.Style(
63
+ display="flex", height="100%", justify_content="center", align_items="center"
64
+ )
65
+ ):
66
+ response_index = prompt_response[1] if prompt_response else "-1"
67
+ _, selected_version_response_index = response_map[prompts[0].version].get(
68
+ response_key
69
+ )
70
+ with me.content_button(
71
+ key=f"run_{row['prompt'].version}_{response_index}_{selected_version_response_index}",
72
+ on_click=on_click_run,
73
+ style=me.Style(background="#EBF1FD", border_radius="10"),
74
+ ):
75
+ with me.tooltip(message="Run prompt"):
76
+ me.icon("play_arrow")
77
  elif row["type"] == "model_rating":
78
  with me.box(style=_RATING_STYLE):
79
  prompt_response = response_map[row["prompt"].version].get(response_key)
80
+ if prompt_response and prompt_response[0]["output"]:
81
  me.select(
82
+ value=prompt_response[0].get("rating", 0),
83
  options=[
84
  me.SelectOption(label="1", value="1"),
85
  me.SelectOption(label="2", value="2"),
handlers.py CHANGED
@@ -23,5 +23,4 @@ def on_update_input(e: me.InputBlurEvent | me.InputEvent | me.InputEnterEvent):
23
  def on_update_selection(e: me.SelectSelectionChangeEvent):
24
  """Generic event to update input values."""
25
  state = me.state(State)
26
- print("EEE", e)
27
  setattr(state, e.key, e.value)
 
23
  def on_update_selection(e: me.SelectSelectionChangeEvent):
24
  """Generic event to update input values."""
25
  state = me.state(State)
 
26
  setattr(state, e.key, e.value)
main.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
  import mesop as me
2
 
3
  import components as mex
@@ -26,6 +28,10 @@ _INSTRUCTIONS = """
26
  def app():
27
  state = me.state(State)
28
 
 
 
 
 
29
  dialogs.update_title()
30
  dialogs.model_settings()
31
  dialogs.prompt_variables()
@@ -33,6 +39,7 @@ def app():
33
  dialogs.add_comparisons()
34
  dialogs.generate_prompt()
35
  dialogs.load_prompt()
 
36
 
37
  with me.box(
38
  style=me.Style(
@@ -125,8 +132,21 @@ def app():
125
  compare_prompts = [
126
  prompt for prompt in state.prompts if prompt.version in state.comparisons
127
  ]
128
- prompt_eval_table([prompt] + compare_prompts, on_select_rating=on_select_rating)
129
-
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  tool_sidebar()
131
 
132
 
@@ -139,6 +159,31 @@ def on_click_system_instructions_header(e: me.ClickEvent):
139
  state.system_prompt_card_expanded = not state.system_prompt_card_expanded
140
 
141
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  def on_click_run(e: me.ClickEvent):
143
  """Runs the prompt with the given variables.
144
 
 
1
+ import copy
2
+
3
  import mesop as me
4
 
5
  import components as mex
 
28
  def app():
29
  state = me.state(State)
30
 
31
+ mex.snackbar(
32
+ is_visible=state.show_snackbar, label=state.snackbar_message, horizontal_position="start"
33
+ )
34
+
35
  dialogs.update_title()
36
  dialogs.model_settings()
37
  dialogs.prompt_variables()
 
39
  dialogs.add_comparisons()
40
  dialogs.generate_prompt()
41
  dialogs.load_prompt()
42
+ dialogs.add_row()
43
 
44
  with me.box(
45
  style=me.Style(
 
132
  compare_prompts = [
133
  prompt for prompt in state.prompts if prompt.version in state.comparisons
134
  ]
135
+ prompt_eval_table(
136
+ [prompt] + compare_prompts,
137
+ on_select_rating=on_select_rating,
138
+ on_click_run=on_click_eval_run,
139
+ )
140
+ me.button(
141
+ label="Add row",
142
+ type="flat",
143
+ style=me.Style(
144
+ margin=me.Margin(top=10),
145
+ border_radius="10",
146
+ ),
147
+ key="dialog_show_add_row",
148
+ on_click=handlers.on_open_dialog,
149
+ )
150
  tool_sidebar()
151
 
152
 
 
159
  state.system_prompt_card_expanded = not state.system_prompt_card_expanded
160
 
161
 
162
+ def on_click_eval_run(e: me.ClickEvent):
163
+ state = me.state(State)
164
+ print(e.key)
165
+ _, prompt_version, response_index, selected_prompt_response_index = e.key.split("_")
166
+ prompt = find_prompt(state.prompts, int(prompt_version))
167
+ selected_prompt = find_prompt(state.prompts, state.version)
168
+ selected_prompt
169
+
170
+ if response_index != "-1":
171
+ response = prompt.responses[int(response_index)]
172
+ else:
173
+ response = {
174
+ "variables": copy.copy(
175
+ selected_prompt.responses[int(selected_prompt_response_index)]["variables"]
176
+ ),
177
+ "rating": 0,
178
+ }
179
+ prompt.responses.append(response)
180
+
181
+ prompt_text = prompt.prompt
182
+ for name, value in response["variables"].items():
183
+ prompt_text = prompt_text.replace("{{" + name + "}}", value)
184
+ response["output"] = llm.run_prompt(prompt_text, prompt.model, prompt.model_temperature)
185
+
186
+
187
  def on_click_run(e: me.ClickEvent):
188
  """Runs the prompt with the given variables.
189
 
state.py CHANGED
@@ -12,9 +12,9 @@ class Prompt:
12
  version: int = 0
13
  variables: list[str] = field(default_factory=list)
14
  # Storing the responses as a dict to workaround bug with lists
15
- # of nested dataclass.
16
  #
17
- # Keys: output, variables, rating
18
  responses: list[dict] = field(default_factory=list)
19
 
20
 
@@ -31,6 +31,7 @@ class State:
31
 
32
  # Prompt variables
33
  prompt_variables: dict[str, str]
 
34
 
35
  # Model info
36
  model: str = "gemini-1.5-flash"
@@ -38,13 +39,14 @@ class State:
38
  model_temperature_input: str = "1.0"
39
 
40
  # Dialogs
41
- dialog_show_title: bool = False
 
 
 
42
  dialog_show_model_settings: bool = False
43
  dialog_show_prompt_variables: bool = False
44
- dialog_show_generate_prompt: bool = False
45
  dialog_show_version_history: bool = False
46
- dialog_show_add_comparison: bool = False
47
- dialog_show_load: bool = False
48
 
49
  prompts: list[Prompt]
50
 
@@ -54,4 +56,9 @@ class State:
54
  # Valid modes: Prompt or Eval
55
  mode: str = "Prompt"
56
 
 
57
  comparisons: list[int]
 
 
 
 
 
12
  version: int = 0
13
  variables: list[str] = field(default_factory=list)
14
  # Storing the responses as a dict to workaround bug with lists
15
+ # of nested dataclass. See https://github.com/google/mesop/issues/659.
16
  #
17
+ # Keys: output: str, variables: dict[str, str], rating: int
18
  responses: list[dict] = field(default_factory=list)
19
 
20
 
 
31
 
32
  # Prompt variables
33
  prompt_variables: dict[str, str]
34
+ add_row_prompt_variables: dict[str, str]
35
 
36
  # Model info
37
  model: str = "gemini-1.5-flash"
 
39
  model_temperature_input: str = "1.0"
40
 
41
  # Dialogs
42
+ dialog_show_add_comparison: bool = False
43
+ dialog_show_add_row: bool = False
44
+ dialog_show_generate_prompt: bool = False
45
+ dialog_show_load: bool = False
46
  dialog_show_model_settings: bool = False
47
  dialog_show_prompt_variables: bool = False
48
+ dialog_show_title: bool = False
49
  dialog_show_version_history: bool = False
 
 
50
 
51
  prompts: list[Prompt]
52
 
 
56
  # Valid modes: Prompt or Eval
57
  mode: str = "Prompt"
58
 
59
+ # Eval comparisons
60
  comparisons: list[int]
61
+
62
+ show_snackbar: bool = False
63
+ snackbar_message: str = ""
64
+ snackbar_duration: int = 2
tool_sidebar.py CHANGED
@@ -3,6 +3,7 @@ import errno
3
  import json
4
  import os
5
  import re
 
6
 
7
  import mesop as me
8
 
@@ -62,9 +63,10 @@ def tool_sidebar():
62
  def on_click_download(e: me.ClickEvent):
63
  state = me.state(State)
64
  cleaned_title = _clean_title(state.title)
 
65
  _create_directory(SAVED_PROMPT_DIRECTORY)
66
 
67
- with open(f"{SAVED_PROMPT_DIRECTORY}/prompt-{cleaned_title}.json", "w") as outfile:
68
  output = {
69
  key: value
70
  for key, value in asdict(state).items()
@@ -80,6 +82,14 @@ def on_click_download(e: me.ClickEvent):
80
  }
81
  json.dump(output, outfile)
82
 
 
 
 
 
 
 
 
 
83
 
84
  def _clean_title(title: str) -> str:
85
  return re.sub(r"[^a-z0-9_]", "", title.lower().replace(" ", "_"))
@@ -89,7 +99,6 @@ def _create_directory(directory_path):
89
  """Creates a directory if it doesn't exist."""
90
  try:
91
  os.makedirs(directory_path)
92
- print(f"Directory '{directory_path}' created successfully.")
93
  except OSError as e:
94
  if e.errno != errno.EEXIST:
95
  raise
 
3
  import json
4
  import os
5
  import re
6
+ import time
7
 
8
  import mesop as me
9
 
 
63
  def on_click_download(e: me.ClickEvent):
64
  state = me.state(State)
65
  cleaned_title = _clean_title(state.title)
66
+ filename = f"prompt-{cleaned_title}.json"
67
  _create_directory(SAVED_PROMPT_DIRECTORY)
68
 
69
+ with open(f"{SAVED_PROMPT_DIRECTORY}/{filename}", "w") as outfile:
70
  output = {
71
  key: value
72
  for key, value in asdict(state).items()
 
82
  }
83
  json.dump(output, outfile)
84
 
85
+ state.snackbar_message = f"Prompt exported as {filename}."
86
+ state.show_snackbar = True
87
+ yield
88
+ time.sleep(state.snackbar_duration)
89
+ yield
90
+ state.show_snackbar = False
91
+ yield
92
+
93
 
94
  def _clean_title(title: str) -> str:
95
  return re.sub(r"[^a-z0-9_]", "", title.lower().replace(" ", "_"))
 
99
  """Creates a directory if it doesn't exist."""
100
  try:
101
  os.makedirs(directory_path)
 
102
  except OSError as e:
103
  if e.errno != errno.EEXIST:
104
  raise