-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add some goldens for writing chat UIs (#919)
* Add some goldens for writing chat UIs - Add simple chat example - Add fancy chat example - Add other examples for enhancing simple chat
- Loading branch information
1 parent
d22087d
commit a7c7a77
Showing
37 changed files
with
5,658 additions
and
1 deletion.
There are no files selected for viewing
69 changes: 69 additions & 0 deletions
69
ai/ft/goldens/Add_dark_mode_icon_on_the_right_end_of_the_header_t1rpJA/diff.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<<<<<<< ORIGINAL | ||
# Fancy header | ||
with me.box( | ||
style=me.Style( | ||
background=me.theme_var("primary"), | ||
padding=me.Padding.all(16), | ||
border_radius=8, | ||
margin=me.Margin(bottom=20), | ||
display="flex", | ||
align_items="center", | ||
) | ||
): | ||
me.icon( | ||
"chat", style=me.Style(color=me.theme_var("on-primary"), font_size=24) | ||
) | ||
me.text( | ||
"AI Chatbot", | ||
style=me.Style( | ||
color=me.theme_var("on-primary"), | ||
font_size=24, | ||
font_weight="bold", | ||
margin=me.Margin(left=12), | ||
), | ||
) | ||
me.text( | ||
"Talk to our intelligent assistant", | ||
style=me.Style( | ||
color=me.theme_var("on-primary"), | ||
font_size=16, | ||
margin=me.Margin(left=12), | ||
), | ||
) | ||
======= | ||
# Fancy header | ||
with me.box( | ||
style=me.Style( | ||
background=me.theme_var("primary"), | ||
padding=me.Padding.all(16), | ||
border_radius=8, | ||
margin=me.Margin(bottom=20), | ||
display="flex", | ||
justify_content="space-between", | ||
) | ||
): | ||
with me.box(style=me.Style(display="flex", align_items="center")): | ||
me.icon( | ||
"chat", style=me.Style(color=me.theme_var("on-primary"), font_size=24) | ||
) | ||
me.text( | ||
"AI Chatbot", | ||
style=me.Style( | ||
color=me.theme_var("on-primary"), | ||
font_size=24, | ||
font_weight="bold", | ||
margin=me.Margin(left=12), | ||
flex_grow=1, | ||
), | ||
) | ||
me.text( | ||
"Talk to our intelligent assistant", | ||
style=me.Style( | ||
color=me.theme_var("on-primary"), | ||
font_size=16, | ||
margin=me.Margin(left=12), | ||
), | ||
) | ||
with me.content_button(type="icon"): | ||
me.icon("dark_mode", style=me.Style(color=me.theme_var("on-primary"))) | ||
>>>>>>> UPDATED |
259 changes: 259 additions & 0 deletions
259
ai/ft/goldens/Add_dark_mode_icon_on_the_right_end_of_the_header_t1rpJA/patched.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,259 @@ | ||
import random | ||
import time | ||
from dataclasses import dataclass | ||
from typing import Literal | ||
|
||
import mesop as me | ||
|
||
Role = Literal["user", "bot"] | ||
|
||
|
||
@dataclass(kw_only=True) | ||
class ChatMessage: | ||
"""Chat message metadata.""" | ||
|
||
role: Role = "user" | ||
content: str = "" | ||
edited: bool = False | ||
|
||
|
||
@me.stateclass | ||
class State: | ||
input: str | ||
output: list[ChatMessage] | ||
in_progress: bool | ||
|
||
|
||
@me.page(path="/ai") | ||
def page(): | ||
state = me.state(State) | ||
with me.box( | ||
style=me.Style( | ||
color=me.theme_var("on-surface"), | ||
background=me.theme_var("surface-container-lowest"), | ||
display="flex", | ||
flex_direction="column", | ||
height="100%", | ||
padding=me.Padding.all(15), | ||
) | ||
): | ||
# Fancy header | ||
with me.box( | ||
style=me.Style( | ||
background=me.theme_var("primary"), | ||
padding=me.Padding.all(16), | ||
border_radius=8, | ||
margin=me.Margin(bottom=20), | ||
display="flex", | ||
justify_content="space-between", | ||
) | ||
): | ||
with me.box(style=me.Style(display="flex", align_items="center")): | ||
me.icon( | ||
"chat", style=me.Style(color=me.theme_var("on-primary"), font_size=24) | ||
) | ||
me.text( | ||
"AI Chatbot", | ||
style=me.Style( | ||
color=me.theme_var("on-primary"), | ||
font_size=24, | ||
font_weight="bold", | ||
margin=me.Margin(left=12), | ||
flex_grow=1, | ||
), | ||
) | ||
me.text( | ||
"Talk to our intelligent assistant", | ||
style=me.Style( | ||
color=me.theme_var("on-primary"), | ||
font_size=16, | ||
margin=me.Margin(left=12), | ||
), | ||
) | ||
with me.content_button(type="icon"): | ||
me.icon("dark_mode", style=me.Style(color=me.theme_var("on-primary"))) | ||
# This contains the chat messages that have been recorded. This takes 50fr. | ||
# This section can be replaced with other types of chat messages. | ||
|
||
# We set overflow to scroll so that the chat input will be fixed at the bottom. | ||
with me.box(style=me.Style(overflow_y="scroll", flex_grow=1)): | ||
for msg in state.output: | ||
# User chat message | ||
if msg.role == "user": | ||
with me.box( | ||
style=me.Style(display="flex", gap=15, margin=me.Margin.all(20)) | ||
): | ||
# User avatar/icon box | ||
me.text( | ||
"U", | ||
style=me.Style( | ||
background=me.theme_var("primary"), | ||
border_radius="50%", | ||
color=me.theme_var("on-primary"), | ||
font_size=20, | ||
height=40, | ||
width=40, | ||
text_align="center", | ||
line_height="1", | ||
padding=me.Padding(top=10), | ||
margin=me.Margin(top=16), | ||
), | ||
) | ||
# User query | ||
me.markdown(msg.content) | ||
else: | ||
# Bot chat message | ||
with me.box( | ||
style=me.Style(display="flex", gap=15, margin=me.Margin.all(20)) | ||
): | ||
# Bot avatar/icon box | ||
me.text( | ||
"B", | ||
style=me.Style( | ||
background=me.theme_var("secondary"), | ||
border_radius="50%", | ||
color=me.theme_var("on-secondary"), | ||
font_size=20, | ||
height=40, | ||
width="40px", | ||
text_align="center", | ||
line_height="1", | ||
padding=me.Padding(top=10), | ||
margin=me.Margin(top=16), | ||
), | ||
) | ||
# Bot message response | ||
me.markdown( | ||
msg.content, | ||
style=me.Style(color=me.theme_var("on-surface")), | ||
) | ||
with me.box( | ||
style=me.Style( | ||
display="flex", | ||
gap=10, | ||
margin=me.Margin(top=8), | ||
) | ||
): | ||
with me.content_button( | ||
type="icon", | ||
style=me.Style( | ||
background=me.theme_var("surface-container-low"), | ||
), | ||
): | ||
me.icon("thumb_up") | ||
with me.content_button( | ||
type="icon", | ||
style=me.Style( | ||
background=me.theme_var("surface-container-low"), | ||
), | ||
): | ||
me.icon("thumb_down") | ||
with me.content_button( | ||
type="icon", | ||
style=me.Style( | ||
background=me.theme_var("surface-container-low"), | ||
), | ||
): | ||
me.icon("refresh") | ||
|
||
# This is for the basic chat input. This is the second row at 1fr. | ||
# This section can be replaced with other types of chat inputs. | ||
with me.box( | ||
style=me.Style( | ||
border_radius=16, | ||
padding=me.Padding.all(8), | ||
background=me.theme_var("surface-container-low"), | ||
display="flex", | ||
width="100%", | ||
) | ||
): | ||
with me.box( | ||
style=me.Style( | ||
flex_grow=1, | ||
) | ||
): | ||
me.native_textarea( | ||
key="chat_input", | ||
value=state.input, | ||
on_blur=on_chat_input, | ||
autosize=True, | ||
min_rows=4, | ||
placeholder="Enter your prompt", | ||
style=me.Style( | ||
color=me.theme_var("on-surface-variant"), | ||
padding=me.Padding(top=16, left=16), | ||
background=me.theme_var("surface-container-low"), | ||
outline="none", | ||
width="100%", | ||
overflow_y="auto", | ||
border=me.Border.all( | ||
me.BorderSide(style="none"), | ||
), | ||
), | ||
) | ||
with me.content_button( | ||
type="icon", | ||
on_click=on_click_submit_chat_msg, | ||
# If we're processing a message prevent new queries from being sent | ||
disabled=state.in_progress, | ||
): | ||
me.icon("send") | ||
|
||
|
||
def on_chat_input(e: me.InputBlurEvent): | ||
"""Capture chat text input on blur.""" | ||
state = me.state(State) | ||
state.input = e.value | ||
|
||
|
||
def on_click_submit_chat_msg(e: me.ClickEvent): | ||
"""Handles submitting a chat message.""" | ||
state = me.state(State) | ||
if state.in_progress or not state.input: | ||
return | ||
input = state.input | ||
# Clear the text input. | ||
state.input = "" | ||
yield | ||
|
||
output = state.output | ||
if output is None: | ||
output = [] | ||
output.append(ChatMessage(role="user", content=input)) | ||
state.in_progress = True | ||
yield | ||
|
||
start_time = time.time() | ||
# Send user input and chat history to get the bot response. | ||
output_message = respond_to_chat(input, state.output) | ||
assistant_message = ChatMessage(role="bot") | ||
output.append(assistant_message) | ||
state.output = output | ||
for content in output_message: | ||
assistant_message.content += content | ||
# TODO: 0.25 is an abitrary choice. In the future, consider making this adjustable. | ||
if (time.time() - start_time) >= 0.25: | ||
start_time = time.time() | ||
yield | ||
|
||
state.in_progress = False | ||
me.focus_component(key="chat_input") | ||
yield | ||
|
||
|
||
def respond_to_chat(input: str, history: list[ChatMessage]): | ||
"""Displays random canned text. | ||
Edit this function to process messages with a real chatbot/LLM. | ||
""" | ||
lines = [ | ||
"Mesop is a Python-based UI framework designed to simplify web UI development for engineers without frontend experience.", | ||
"It leverages the power of the Angular web framework and Angular Material components, allowing rapid construction of web demos and internal tools.", | ||
"With Mesop, developers can enjoy a fast build-edit-refresh loop thanks to its hot reload feature, making UI tweaks and component integration seamless.", | ||
"Deployment is straightforward, utilizing standard HTTP technologies.", | ||
"Mesop's component library aims for comprehensive Angular Material component coverage, enhancing UI flexibility and composability.", | ||
"It supports custom components for specific use cases, ensuring developers can extend its capabilities to fit their unique requirements.", | ||
"Mesop's roadmap includes expanding its component library and simplifying the onboarding processs.", | ||
] | ||
for line in random.sample(lines, random.randint(3, len(lines) - 1)): | ||
yield line + " " |
1 change: 1 addition & 0 deletions
1
ai/ft/goldens/Add_dark_mode_icon_on_the_right_end_of_the_header_t1rpJA/prompt.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add dark mode icon on the right end of the header |
Oops, something went wrong.