-
Notifications
You must be signed in to change notification settings - Fork 0
/
chat.py
100 lines (85 loc) · 2.55 KB
/
chat.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import openai
import solara as sl
from solara.alias import rv
from dataclasses import dataclass, asdict
from typing import List, Iterator
chatbox_css = """
.message {
max-width: 450px;
width: 100%;
}
.system-message, .system-message > * {
background-color: #ffffff !important;
}
.user-message, .user-message > * {
background-color: #f0f0f0 !important;
}
.assistant-message, .assistant-message > * {
background-color: #9ab2e9 !important;
}
.avatar {
width: 50px;
height: 50px;
border-radius: 50%;
border: 2px solid transparent;
overflow: hidden;
display: flex;
}
.avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
"""
@dataclass
class Message:
role: str
content: str
def get_chatgpt_response(messages: List[Message]) -> Iterator[Message]:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[asdict(m) for m in messages],
temperature=0.1,
stream=True
)
total = ""
for chunk in response:
part = chunk['choices'][0]['delta'].get("content", "")
total += part
yield Message(role="assistant", content=total)
def ChatBox(message: Message) -> None:
sl.Style(chatbox_css)
align = "start" if message.role == "assistant" else "center" if message.role == "system" else "end"
with sl.Column(align=align):
with sl.Card(classes=["message", f"{message.role}-message"]):
sl.Markdown(message.content)
with sl.HBox(align_items="center"):
sl.Image(f"{message.role}-logo.png", classes=["avatar"])
sl.Text(message.role.capitalize())
@sl.component
def Chat() -> None:
sl.Style("""
.chat-input {
max-width: 800px;
})
""")
messages, set_messages = sl.use_state([
Message(
role="system",
content="Assist the user with whatever they need.")
]
)
input, set_input = sl.use_state("")
def ask_chatgpt():
_messages = messages + [Message(role="user", content=input)]
set_input("")
set_messages(_messages)
for new_message in get_chatgpt_response(_messages):
set_messages(_messages + [new_message])
with sl.VBox():
for message in messages:
ChatBox(message)
with sl.Row(justify="center"):
with sl.HBox(align_items="center", classes=["chat-input"]):
rv.Textarea(v_model=input, on_v_model=set_input, solo=True, hide_details=True, outlined=True, rows=1, auto_grow=True)
sl.IconButton("send", on_click=ask_chatgpt)