Skip to content

Commit 9e37ee6

Browse files
authored
improve handling of chat state (#54)
1 parent 060cd3e commit 9e37ee6

File tree

3 files changed

+35
-24
lines changed

3 files changed

+35
-24
lines changed

chat/components/chat.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ def message(qa: QA) -> rx.Component:
5252
def chat() -> rx.Component:
5353
"""List all the messages in a single conversation."""
5454
return rx.auto_scroll(
55-
rx.foreach(
56-
State.chats[State.current_chat],
57-
message,
58-
),
55+
rx.foreach(State.selected_chat, message),
5956
flex="1",
6057
padding="8px",
6158
)

chat/components/navbar.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@ def sidebar_chat(chat: str) -> rx.Component:
1919
rx.button(
2020
rx.icon(
2121
tag="trash",
22-
on_click=State.delete_chat,
22+
on_click=State.delete_chat(chat),
2323
stroke_width=1,
2424
),
2525
width="20%",
2626
variant="surface",
2727
color_scheme="red",
2828
),
2929
width="100%",
30-
)
30+
),
31+
key=chat,
3132
)
3233

3334

chat/state.py

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@ class QA(TypedDict):
1616
answer: str
1717

1818

19-
DEFAULT_CHATS = {
20-
"Intros": [],
21-
}
22-
23-
2419
class State(rx.State):
2520
"""The app state."""
2621

2722
# A dict from the chat name to the list of questions and answers.
28-
chats: dict[str, list[QA]] = DEFAULT_CHATS
23+
_chats: dict[str, list[QA]] = {
24+
"Intros": [],
25+
}
2926

3027
# The current chat name.
3128
current_chat = "Intros"
@@ -41,15 +38,31 @@ def create_chat(self):
4138
"""Create a new chat."""
4239
# Add the new chat to the list of chats.
4340
self.current_chat = self.new_chat_name
44-
self.chats[self.new_chat_name] = []
41+
self._chats[self.new_chat_name] = []
42+
43+
@rx.var
44+
def selected_chat(self) -> list[QA]:
45+
"""Get the list of questions and answers for the current chat.
46+
47+
Returns:
48+
The list of questions and answers.
49+
"""
50+
return (
51+
self._chats[self.current_chat] if self.current_chat in self._chats else []
52+
)
4553

4654
@rx.event
47-
def delete_chat(self):
55+
def delete_chat(self, chat_name: str):
4856
"""Delete the current chat."""
49-
del self.chats[self.current_chat]
50-
if len(self.chats) == 0:
51-
self.chats = DEFAULT_CHATS
52-
self.current_chat = list(self.chats.keys())[0]
57+
if chat_name not in self._chats:
58+
return
59+
del self._chats[chat_name]
60+
if len(self._chats) == 0:
61+
self._chats = {
62+
"Intros": [],
63+
}
64+
if self.current_chat not in self._chats:
65+
self.current_chat = list(self._chats.keys())[0]
5366

5467
@rx.event
5568
def set_chat(self, chat_name: str):
@@ -76,7 +89,7 @@ def chat_titles(self) -> list[str]:
7689
Returns:
7790
The list of chat names.
7891
"""
79-
return list(self.chats.keys())
92+
return list(self._chats.keys())
8093

8194
@rx.event
8295
async def process_question(self, form_data: dict[str, Any]):
@@ -100,7 +113,7 @@ async def openai_process_question(self, question: str):
100113

101114
# Add the question to the list of questions.
102115
qa = QA(question=question, answer="")
103-
self.chats[self.current_chat].append(qa)
116+
self._chats[self.current_chat].append(qa)
104117

105118
# Clear the input and start the processing.
106119
self.processing = True
@@ -113,7 +126,7 @@ async def openai_process_question(self, question: str):
113126
"content": "You are a friendly chatbot named Reflex. Respond in markdown.",
114127
}
115128
]
116-
for qa in self.chats[self.current_chat]:
129+
for qa in self._chats[self.current_chat]:
117130
messages.append({"role": "user", "content": qa["question"]})
118131
messages.append({"role": "assistant", "content": qa["answer"]})
119132

@@ -133,13 +146,13 @@ async def openai_process_question(self, question: str):
133146
answer_text = item.choices[0].delta.content
134147
# Ensure answer_text is not None before concatenation
135148
if answer_text is not None:
136-
self.chats[self.current_chat][-1]["answer"] += answer_text
149+
self._chats[self.current_chat][-1]["answer"] += answer_text
137150
else:
138151
# Handle the case where answer_text is None, perhaps log it or assign a default value
139152
# For example, assigning an empty string if answer_text is None
140153
answer_text = ""
141-
self.chats[self.current_chat][-1]["answer"] += answer_text
142-
self.chats = self.chats
154+
self._chats[self.current_chat][-1]["answer"] += answer_text
155+
self._chats = self._chats
143156
yield
144157

145158
# Toggle the processing flag.

0 commit comments

Comments
 (0)