Gonalb commited on
Commit
b2b0814
·
1 Parent(s): f2fde2c

add chat history

Browse files
Files changed (1) hide show
  1. app.py +165 -29
app.py CHANGED
@@ -2,6 +2,12 @@ import chainlit as cl
2
  import pandas as pd
3
  import time
4
  from typing import Dict, Any
 
 
 
 
 
 
5
 
6
  from agents.table_selection import table_selection_agent
7
  from agents.data_retrieval import sample_data_retrieval_agent
@@ -11,42 +17,172 @@ from agents.execution import execution_agent
11
  from utils.bigquery_utils import init_bigquery_connection
12
  from utils.feedback_utils import save_feedback_to_bigquery
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  @cl.on_chat_start
15
- async def on_chat_start():
16
- """Initialize the chat session."""
17
- # Initialize BigQuery client
18
- client = init_bigquery_connection()
19
 
20
- # Store the client in the user session
21
- cl.user_session.set("client", client)
22
 
23
- # Send a welcome message
24
- await cl.Message(
25
- content="👋 Welcome to the Natural Language to SQL Query Assistant! Ask me any question about your e-commerce data.",
26
- author="SQL Assistant"
27
- ).send()
28
 
29
- # Add some example questions without using actions
30
- await cl.Message(
31
- content="Here are some example questions you can ask:",
32
- author="SQL Assistant"
33
- ).send()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- examples = [
36
- "What are the top 5 products by revenue?",
37
- "How many orders were placed in the last month?",
38
- "Which customers spent the most in 2023?",
39
- "What is the average order value by product category?"
40
- ]
 
 
 
41
 
42
- # Display all examples in a single message
43
- examples_text = "\n\n".join([f"• {example}" for example in examples])
44
- examples_text += "\n\n(You can copy and paste any of these examples to try them out)"
45
 
46
- await cl.Message(
47
- content=examples_text,
48
- author="SQL Assistant"
49
- ).send()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  @cl.on_message
52
  async def on_message(message: cl.Message):
 
2
  import pandas as pd
3
  import time
4
  from typing import Dict, Any
5
+ from chainlit.session import get_session
6
+ import os
7
+ import json
8
+ from datetime import datetime
9
+ import hashlib
10
+ import uuid
11
 
12
  from agents.table_selection import table_selection_agent
13
  from agents.data_retrieval import sample_data_retrieval_agent
 
17
  from utils.bigquery_utils import init_bigquery_connection
18
  from utils.feedback_utils import save_feedback_to_bigquery
19
 
20
+ # File to store chat history
21
+ HISTORY_DIR = "chat_history"
22
+ os.makedirs(HISTORY_DIR, exist_ok=True)
23
+
24
+ # Function to get or create a user ID
25
+ def get_user_id(session):
26
+ # Check if user already has an ID
27
+ user_id = session.user_session.get("user_id")
28
+
29
+ if not user_id:
30
+ # Generate a new user ID if none exists
31
+ # In a real app, you might use authentication or cookies
32
+ user_id = str(uuid.uuid4())
33
+ session.user_session.set("user_id", user_id)
34
+
35
+ # Create a user directory for this user
36
+ user_dir = os.path.join(HISTORY_DIR, user_id)
37
+ os.makedirs(user_dir, exist_ok=True)
38
+
39
+ return user_id
40
+
41
+ # Function to save chat history
42
+ def save_chat_history(user_id, conversation_id, user_message, assistant_response):
43
+ user_dir = os.path.join(HISTORY_DIR, user_id)
44
+ os.makedirs(user_dir, exist_ok=True)
45
+
46
+ history_file = os.path.join(user_dir, f"{conversation_id}.json")
47
+
48
+ # Load existing history if it exists
49
+ if os.path.exists(history_file):
50
+ with open(history_file, 'r') as f:
51
+ history = json.load(f)
52
+ else:
53
+ history = {
54
+ "conversation_id": conversation_id,
55
+ "created_at": datetime.now().isoformat(),
56
+ "messages": []
57
+ }
58
+
59
+ # Add new messages
60
+ timestamp = datetime.now().isoformat()
61
+ history["messages"].append({
62
+ "timestamp": timestamp,
63
+ "user": user_message,
64
+ "assistant": assistant_response
65
+ })
66
+
67
+ # Save updated history
68
+ with open(history_file, 'w') as f:
69
+ json.dump(history, f, indent=2)
70
+
71
+ # Function to load chat history for a user
72
+ def load_chat_history(user_id, conversation_id=None):
73
+ user_dir = os.path.join(HISTORY_DIR, user_id)
74
+
75
+ if not os.path.exists(user_dir):
76
+ return []
77
+
78
+ if conversation_id:
79
+ # Load specific conversation
80
+ history_file = os.path.join(user_dir, f"{conversation_id}.json")
81
+ if os.path.exists(history_file):
82
+ with open(history_file, 'r') as f:
83
+ return json.load(f)
84
+ return None
85
+ else:
86
+ # Load all conversations (just metadata)
87
+ conversations = []
88
+ for filename in os.listdir(user_dir):
89
+ if filename.endswith('.json'):
90
+ with open(os.path.join(user_dir, filename), 'r') as f:
91
+ data = json.load(f)
92
+ conversations.append({
93
+ "conversation_id": data["conversation_id"],
94
+ "created_at": data["created_at"],
95
+ "message_count": len(data["messages"])
96
+ })
97
+ return sorted(conversations, key=lambda x: x["created_at"], reverse=True)
98
+
99
  @cl.on_chat_start
100
+ async def start():
101
+ # Get the current session
102
+ session = get_session()
 
103
 
104
+ # Get or create user ID
105
+ user_id = get_user_id(session)
106
 
107
+ # Create a new conversation ID for this session
108
+ conversation_id = str(uuid.uuid4())
109
+ session.user_session.set("conversation_id", conversation_id)
 
 
110
 
111
+ # Load previous conversations for this user
112
+ conversations = load_chat_history(user_id)
113
+
114
+ if conversations:
115
+ # Display a welcome back message
116
+ await cl.Message(
117
+ content=f"Welcome back! You have {len(conversations)} previous conversations.",
118
+ ).send()
119
+
120
+ # Create a dropdown to select previous conversations
121
+ options = [{"value": conv["conversation_id"], "label": f"Conversation from {conv['created_at'][:10]} ({conv['message_count']} messages)"} for conv in conversations]
122
+ options.insert(0, {"value": "new", "label": "Start a new conversation"})
123
+
124
+ res = await cl.AskUserMessage(
125
+ content="Would you like to continue a previous conversation or start a new one?",
126
+ timeout=30,
127
+ select={"options": options, "value": "new"}
128
+ ).send()
129
+
130
+ if res and res.get("value") != "new":
131
+ # User selected a previous conversation
132
+ selected_conv_id = res.get("value")
133
+ session.user_session.set("conversation_id", selected_conv_id)
134
+
135
+ # Load the selected conversation
136
+ conversation = load_chat_history(user_id, selected_conv_id)
137
+ if conversation:
138
+ # Display previous messages
139
+ await cl.Message(content="Loading your previous conversation...").send()
140
+ for msg in conversation["messages"]:
141
+ await cl.Message(content=msg["user"], author="You").send()
142
+ await cl.Message(content=msg["assistant"]).send()
143
+ else:
144
+ # First time user
145
+ await cl.Message(
146
+ content="Welcome to the E-commerce Analytics Assistant! How can I help you today?",
147
+ ).send()
148
 
149
+ # Add option to clear history
150
+ await cl.Action(name="clear_history", label="Clear Chat History", description="Erase all previous conversation history").send()
151
+
152
+ @cl.on_message
153
+ async def on_message(message: cl.Message):
154
+ # Get the current session
155
+ session = get_session()
156
+ user_id = session.user_session.get("user_id")
157
+ conversation_id = session.user_session.get("conversation_id")
158
 
159
+ # Process the message and generate a response
160
+ # Replace this with your actual processing logic
161
+ response = f"You said: {message.content}"
162
 
163
+ # Send the response
164
+ await cl.Message(content=response).send()
165
+
166
+ # Save to chat history
167
+ save_chat_history(user_id, conversation_id, message.content, response)
168
+
169
+ @cl.action_callback("clear_history")
170
+ async def clear_history_callback(action):
171
+ session = get_session()
172
+ user_id = session.user_session.get("user_id")
173
+ conversation_id = session.user_session.get("conversation_id")
174
+
175
+ # Clear specific conversation or all conversations
176
+ user_dir = os.path.join(HISTORY_DIR, user_id)
177
+ history_file = os.path.join(user_dir, f"{conversation_id}.json")
178
+
179
+ if os.path.exists(history_file):
180
+ os.remove(history_file)
181
+ await cl.Message(content="Your current conversation history has been cleared.").send()
182
+
183
+ # Create a new conversation ID
184
+ new_conversation_id = str(uuid.uuid4())
185
+ session.user_session.set("conversation_id", new_conversation_id)
186
 
187
  @cl.on_message
188
  async def on_message(message: cl.Message):