anumaurya114exp commited on
Commit
4099f5c
·
1 Parent(s): 5cb76b5

added different history and context for different logins

Browse files
Files changed (4) hide show
  1. app.py +24 -11
  2. configProd.py +2 -1
  3. gptManager.py +31 -5
  4. queryHelperManagerCoT.py +65 -11
app.py CHANGED
@@ -14,7 +14,6 @@ from config import *
14
  from constants import *
15
  from utils import *
16
  from gptManager import ChatgptManager
17
- from queryHelperManager import QueryHelper
18
  from queryHelperManagerCoT import QueryHelperChainOfThought
19
 
20
 
@@ -24,6 +23,7 @@ pd.set_option('display.max_rows', None)
24
  # Filter out all warning messages
25
  warnings.filterwarnings("ignore")
26
 
 
27
  dbCreds = DataWrapper(DB_CREDS_DATA)
28
  dbEngine = DbEngine(dbCreds)
29
  print("getting tablesAndCols..")
@@ -48,24 +48,31 @@ queryHelperCot = QueryHelperChainOfThought(gptInstanceForCoT=gptInstanceForCoT,
48
  def checkAuth(username, password):
49
  global ADMIN, PASSWD
50
  if username == ADMIN and password == PASSWD:
51
- return True
 
 
52
  return False
53
 
54
-
55
  # Function to save history of chat
56
- def respondCoT(message, chatHistory):
57
  """gpt response handler for gradio ui"""
58
  global queryHelperCot
 
 
59
  try:
60
- botMessage = queryHelperCot.getQueryForUserInputCoT(message)
 
 
61
  except Exception as e:
62
- errorMessage = {"function":"queryHelperCot.getQueryForUserInput","error":str(e), "userInput":message}
63
  saveLog(errorMessage, 'error')
64
  raise ValueError(str(e))
65
- logMessage = {"userInput":message, "completeGptResponse":botMessage, "function":"queryHelperCot.getQueryForUserInputCoT"}
 
66
  saveLog(logMessage)
67
  chatHistory.append((message, botMessage))
68
- return "", chatHistory
 
69
 
70
 
71
  def preProcessSQL(sql):
@@ -206,13 +213,19 @@ def onSyncLogsWithDataDir():
206
 
207
 
208
  with gr.Blocks() as demo:
209
-
 
210
  with gr.Tab("Query Helper"):
211
  gr.Markdown("""<h1><center> Query Helper</center></h1>""")
212
  chatbot = gr.Chatbot()
213
  msg = gr.Textbox()
214
- clear = gr.ClearButton([msg, chatbot])
215
- msg.submit(respondCoT, [msg, chatbot], [msg, chatbot])
 
 
 
 
 
216
 
217
  # screen 2 : To run sql query against database
218
  with gr.Tab("Run Query"):
 
14
  from constants import *
15
  from utils import *
16
  from gptManager import ChatgptManager
 
17
  from queryHelperManagerCoT import QueryHelperChainOfThought
18
 
19
 
 
23
  # Filter out all warning messages
24
  warnings.filterwarnings("ignore")
25
 
26
+ LOGGED_IN_USERS = []
27
  dbCreds = DataWrapper(DB_CREDS_DATA)
28
  dbEngine = DbEngine(dbCreds)
29
  print("getting tablesAndCols..")
 
48
  def checkAuth(username, password):
49
  global ADMIN, PASSWD
50
  if username == ADMIN and password == PASSWD:
51
+ LOGGED_IN_USERS.append(username)
52
+ print("user logged in...",username)
53
+ return True
54
  return False
55
 
 
56
  # Function to save history of chat
57
+ def respondCoT(message, chatHistory, verboseChatHistory, loggedUser):
58
  """gpt response handler for gradio ui"""
59
  global queryHelperCot
60
+ if len(loggedUser)==0:
61
+ loggedUser.append(LOGGED_IN_USERS[-1])
62
  try:
63
+ # botMessage = queryHelperCot.getQueryForUserInputCoT(message)
64
+ botMessage, verboseBotMessage = queryHelperCot.getQueryForUserInputWithHistory(verboseChatHistory, message)
65
+
66
  except Exception as e:
67
+ errorMessage = {"function":"queryHelperCot.getQueryForUserInputWithHistory","error":str(e), "userInput":message}
68
  saveLog(errorMessage, 'error')
69
  raise ValueError(str(e))
70
+ logMessage = {"userInput":message, "completeGptResponse":verboseBotMessage,
71
+ "parsedResponse":botMessage, "function":"queryHelperCot.getQueryForUserInputWithHistory"}
72
  saveLog(logMessage)
73
  chatHistory.append((message, botMessage))
74
+ verboseChatHistory.append((message, verboseBotMessage))
75
+ return "", chatHistory, verboseChatHistory, loggedUser
76
 
77
 
78
  def preProcessSQL(sql):
 
213
 
214
 
215
  with gr.Blocks() as demo:
216
+ loggedUser = gr.State([])
217
+ verboseChatHistory = gr.State([])
218
  with gr.Tab("Query Helper"):
219
  gr.Markdown("""<h1><center> Query Helper</center></h1>""")
220
  chatbot = gr.Chatbot()
221
  msg = gr.Textbox()
222
+ def clearChatHistory():
223
+ return []
224
+
225
+ clear = gr.ClearButton([msg, chatbot, verboseChatHistory], value="Clear Chat")
226
+ clearButton = gr.Button("Clear Context")
227
+ clearButton.click(clearChatHistory, inputs=None, outputs=[verboseChatHistory])
228
+ msg.submit(respondCoT, [msg, chatbot, verboseChatHistory, loggedUser], [msg, chatbot, verboseChatHistory, loggedUser])
229
 
230
  # screen 2 : To run sql query against database
231
  with gr.Tab("Run Query"):
configProd.py CHANGED
@@ -27,4 +27,5 @@ logsDir = STORAGE_DIR
27
 
28
  TABLES_DATA_DIR = os.path.join(STORAGE_DIR, "tablesData")
29
  RESULT_CSV_DIR = os.path.join(STORAGE_DIR, "csvResults")
30
- SCHEMA_INFO_FILE_PATH = os.path.join(STORAGE_DIR, "schemaInfo.pickle")
 
 
27
 
28
  TABLES_DATA_DIR = os.path.join(STORAGE_DIR, "tablesData")
29
  RESULT_CSV_DIR = os.path.join(STORAGE_DIR, "csvResults")
30
+ SCHEMA_INFO_FILE_PATH = os.path.join(STORAGE_DIR, "schemaInfo.pickle")
31
+ # USERS_INFO_FILE_PATH = os.path.join(STORAGE_DIR, "usersInfo.pickle")
gptManager.py CHANGED
@@ -17,13 +17,39 @@ class ChatgptManager:
17
  else:
18
  del self.messages[0]
19
  self.messages.insert(0, systemMessage)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  def getResponseForUserInput(self, userInput):
22
  #send only recent history to gpt.
23
- self.messages = self.getRecentContextOnly()
24
  userMessage = {"role":"user", "content":userInput}
25
  self.messages.append(userMessage)
26
  print(self.messages, "messages being sent to gpt for completion.")
 
27
  try:
28
  completion = self.client.chat.completions.create(
29
  model=self.model,
@@ -39,8 +65,8 @@ class ChatgptManager:
39
  self.messages.append({"role": "assistant", "content": gptResponse})
40
  return gptResponse
41
 
42
- def getRecentContextOnly(self):
43
  #take only systemp prompt and recent self.contextHistoryLen user input and self.contextHistoryLen assistant messages
44
- if len(self.messages)<2*self.contextHistoryLen+1:
45
- return self.messages[:]
46
- return [self.messages[0]] + self.messages[-2*self.contextHistoryLen:]
 
17
  else:
18
  del self.messages[0]
19
  self.messages.insert(0, systemMessage)
20
+
21
+ def getResponseForChatHistory(self, chatHistory, userInput):
22
+ """
23
+ Assume incoming chat History as [("user message", "bot message"), ("user message", "bot message")]
24
+ and systemp prompt is fixed.
25
+ """
26
+ messages = [self.messages[0]]
27
+ for history in chatHistory:
28
+ userMessage, botMessage = history
29
+ messages.append({"role":"user", "content":userMessage})
30
+ messages.append({"role":"assistant", "content":botMessage})
31
+ messages = self.getRecentContextOnly(messages)
32
+ messages.append({"role":"user", "content":userInput})
33
+ try:
34
+ completion = self.client.chat.completions.create(
35
+ model=self.model,
36
+ messages=messages,
37
+ temperature=0,
38
+ )
39
+ gptResponse = completion.choices[0].message.content
40
+ except Exception as e:
41
+ if not self.throwError:
42
+ errorText = "Error while connecting with gpt " + str(e)[:100] + "..."
43
+ return errorText
44
+ return gptResponse
45
 
46
  def getResponseForUserInput(self, userInput):
47
  #send only recent history to gpt.
48
+ self.messages = self.getRecentContextOnly(self.messages)
49
  userMessage = {"role":"user", "content":userInput}
50
  self.messages.append(userMessage)
51
  print(self.messages, "messages being sent to gpt for completion.")
52
+ print(help(self.client.chat.completions.create),'\n\n\n')
53
  try:
54
  completion = self.client.chat.completions.create(
55
  model=self.model,
 
65
  self.messages.append({"role": "assistant", "content": gptResponse})
66
  return gptResponse
67
 
68
+ def getRecentContextOnly(self, messages):
69
  #take only systemp prompt and recent self.contextHistoryLen user input and self.contextHistoryLen assistant messages
70
+ if len(messages)<2*self.contextHistoryLen+1:
71
+ return messages[:]
72
+ return [messages[0]] + messages[-2*self.contextHistoryLen:]
queryHelperManagerCoT.py CHANGED
@@ -37,6 +37,50 @@ class QueryHelperChainOfThought:
37
  self.metadataLayout = metadataLayout
38
  self._onMetadataChange()
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  def getQueryForUserInputCoT(self, userInput):
41
  prompt = self.getPromptForCot()
42
  self.gptInstanceForCoT.setSystemPrompt(prompt)
@@ -45,10 +89,11 @@ class QueryHelperChainOfThought:
45
  parsedSql = False
46
  if tryParsing:
47
  try:
48
- txt = gptResponse.split("```json")[-1].split('```')[0].replace('\n', '')
49
  sqlResult = json.loads(txt)['finalResult']
50
  parsedSql = True
51
  tryParsing = False
 
52
  except:
53
  print("Couldn't parse desired result from gpt response using method 1.")
54
  if tryParsing:
@@ -56,8 +101,17 @@ class QueryHelperChainOfThought:
56
  sqlResult = json.loads(gptResponse)['finalResult']
57
  parsedSql = True
58
  tryParsing = False
 
59
  except:
60
  print("Couldn't parse desired result from gpt response using method 2")
 
 
 
 
 
 
 
 
61
  if parsedSql:
62
  isFormatted = False
63
  try:
@@ -100,7 +154,7 @@ class QueryHelperChainOfThought:
100
  },
101
  "subquery2": {
102
  "inputSubquery": ["subquery1"],
103
- "description":"extracts state, category, and total sales information from a subquery named "subquery1," filtering the results to include only categories with ranks up to 5 and sorting them by state and category rank."
104
  "result":"SELECT state, category, total_sales
105
  FROM ranked_categories
106
  WHERE category_rank <= 5
@@ -126,13 +180,13 @@ ORDER BY state, category_rank"
126
  promptColumnsInfo = self.getSystemPromptForQuery(selectedTablesAndCols)
127
 
128
  prompt = f"""You are a powerful text to sql model. Your task is to return sql query which answers
129
- user's input. Please follow subquery structure if the sql needs to have multiple subqueries.
130
  ###example userInput is {egUserInput}. output is {cotSubtaskOutput}. Output should be in json format as provided. Only output should be in response, nothing else.\n\n
131
  tables information are {promptTableInfo}.
132
- columns data are {promptColumnsInfo}.
133
  """
134
 
135
- prompt += f"and table Relations are {TABLE_RELATIONS}"
136
 
137
  return prompt
138
 
@@ -145,11 +199,11 @@ ORDER BY state, category_rank"
145
  promptTableInfo = f"""You are a powerful text to sql model. Answer which tables and columns are needed
146
  to answer user input using sql query. and following are tables and columns info. and example user input and result query."""
147
  for idx, tableName in enumerate(selectedTablesAndCols.keys(), start=1):
148
- promptTableInfo += f"table name {tableName} and summary is {tableSummaryDict[tableName]}"
149
- promptTableInfo += f" and columns {', '.join(selectedTablesAndCols[tableName])} \n"
150
  promptTableInfo += "XXXX"
151
  #Join statements
152
- promptTableInfo += f"and table Relations are {TABLE_RELATIONS}"
153
  return promptTableInfo
154
 
155
 
@@ -166,9 +220,9 @@ GROUP BY a.customer_id
166
  ORDER BY chandelier_count DESC"""
167
 
168
  question = "top 5 customers who bought most chandeliers in nov 2023"
169
- promptForQuery = f"""You are a powerful text to sql model. Answer user input with sql query. And the query needs to run on {platform}. and schemaName is {schemaName}. There is example user input and desired generated sql query. Follow similar patterns as example. eg case insensitive, explicit variable declaration etc. user input : {question}, query : {exampleQuery}. and table's data is \n"""
170
  for idx, tableName in enumerate(prospectTablesAndCols.keys(), start=1):
171
- promptForQuery += f"table name is {tableName}, table data is {self.sampleData[tableName][prospectTablesAndCols[tableName]].head(self.gptSampleRows)}"
172
- promptForQuery += f"and table Relations are {TABLE_RELATIONS}"
173
  return promptForQuery.replace("\\"," ").replace(" "," ").replace("XXXX", " ")
174
 
 
37
  self.metadataLayout = metadataLayout
38
  self._onMetadataChange()
39
 
40
+ def getQueryForUserInputWithHistory(self, verboseChatHistory, userInput):
41
+ prompt = self.getPromptForCot()
42
+ self.gptInstanceForCoT.setSystemPrompt(prompt)
43
+ gptResponse = self.gptInstanceForCoT.getResponseForChatHistory(verboseChatHistory, userInput)
44
+ verboseResponse = gptResponse
45
+ tryParsing = True
46
+ parsedSql = False
47
+ if tryParsing:
48
+ try:
49
+ txt = gptResponse.split("```json")[-1].split('```')[0].replace('\n', ' ')
50
+ sqlResult = json.loads(txt)['finalResult']
51
+ parsedSql = True
52
+ tryParsing = False
53
+ print("parsed desired result from gpt response using method 1.")
54
+ except:
55
+ print("Couldn't parse desired result from gpt response using method 1.")
56
+ if tryParsing:
57
+ try:
58
+ sqlResult = json.loads(gptResponse.replace("```json","").replace("```","").replace('\n', ' '))['finalResult']
59
+ parsedSql = True
60
+ tryParsing = False
61
+ print("parsed desired result from gpt response using method 2.")
62
+ except:
63
+ print("Couldn't parse desired result from gpt response using method 2")
64
+ if parsedSql:
65
+ isFormatted = False
66
+ try:
67
+ formattedSql = sqlparse.format(sqlResult, reindent=True)
68
+ responseToReturn = formattedSql
69
+ isFormatted = True
70
+ except:
71
+ isFormatted = False
72
+ if not isFormatted:
73
+ try:
74
+ formattedSql = sqlparse.format(sqlResult['result'], reindent=True)
75
+ responseToReturn = formattedSql
76
+ print("gpt didn't give parsed result. So parsing again. the formatting.")
77
+ except:
78
+ responseToReturn = str(sqlResult)
79
+ else:
80
+ responseToReturn = gptResponse
81
+ return responseToReturn, verboseResponse
82
+
83
+
84
  def getQueryForUserInputCoT(self, userInput):
85
  prompt = self.getPromptForCot()
86
  self.gptInstanceForCoT.setSystemPrompt(prompt)
 
89
  parsedSql = False
90
  if tryParsing:
91
  try:
92
+ txt = gptResponse.split("```json")[-1].split('```')[0].replace('\n', ' ')
93
  sqlResult = json.loads(txt)['finalResult']
94
  parsedSql = True
95
  tryParsing = False
96
+ print("parsed desired result from gpt response using method 1.")
97
  except:
98
  print("Couldn't parse desired result from gpt response using method 1.")
99
  if tryParsing:
 
101
  sqlResult = json.loads(gptResponse)['finalResult']
102
  parsedSql = True
103
  tryParsing = False
104
+ print("parsed desired result from gpt response using method 2.")
105
  except:
106
  print("Couldn't parse desired result from gpt response using method 2")
107
+ if tryParsing:
108
+ try:
109
+ sqlResult = json.loads(gptResponse.replace("```json","").replace("```","").replace('\n', ' '))['finalResult']
110
+ parsedSql = True
111
+ tryParsing = False
112
+ print("parsed desired result from gpt response using method 3.")
113
+ except:
114
+ print("Couldn't parse desired result from gpt response using method 3")
115
  if parsedSql:
116
  isFormatted = False
117
  try:
 
154
  },
155
  "subquery2": {
156
  "inputSubquery": ["subquery1"],
157
+ "description":"extracts state, category, and total sales information from a subquery named subquery1, filtering the results to include only categories with ranks up to 5 and sorting them by state and category rank.",
158
  "result":"SELECT state, category, total_sales
159
  FROM ranked_categories
160
  WHERE category_rank <= 5
 
180
  promptColumnsInfo = self.getSystemPromptForQuery(selectedTablesAndCols)
181
 
182
  prompt = f"""You are a powerful text to sql model. Your task is to return sql query which answers
183
+ user's input. Please follow subquery structure if the sql needs to have multiple subqueries. Your response should be in JSON format.
184
  ###example userInput is {egUserInput}. output is {cotSubtaskOutput}. Output should be in json format as provided. Only output should be in response, nothing else.\n\n
185
  tables information are {promptTableInfo}.
186
+ columns data are {promptColumnsInfo}.
187
  """
188
 
189
+ prompt += f"and table Relations are {TABLE_RELATIONS} "
190
 
191
  return prompt
192
 
 
199
  promptTableInfo = f"""You are a powerful text to sql model. Answer which tables and columns are needed
200
  to answer user input using sql query. and following are tables and columns info. and example user input and result query."""
201
  for idx, tableName in enumerate(selectedTablesAndCols.keys(), start=1):
202
+ promptTableInfo += f"table name {tableName} and summary is {tableSummaryDict[tableName]} "
203
+ promptTableInfo += f" and columns {', '.join(selectedTablesAndCols[tableName])} \n "
204
  promptTableInfo += "XXXX"
205
  #Join statements
206
+ promptTableInfo += f" and table Relations are {TABLE_RELATIONS} "
207
  return promptTableInfo
208
 
209
 
 
220
  ORDER BY chandelier_count DESC"""
221
 
222
  question = "top 5 customers who bought most chandeliers in nov 2023"
223
+ promptForQuery = f"""You are a powerful text to sql model. Answer user input with sql query. And the query needs to run on {platform}. and schemaName is {schemaName}. There is example user input and desired generated sql query. Follow similar patterns as example. eg case insensitive, explicit variable declaration etc. user input : {question}, query : {exampleQuery}. and table's data is \n """
224
  for idx, tableName in enumerate(prospectTablesAndCols.keys(), start=1):
225
+ promptForQuery += f"table name is {tableName}, table data is {self.sampleData[tableName][prospectTablesAndCols[tableName]].head(self.gptSampleRows)} \n "
226
+ promptForQuery += f"and table Relations are {TABLE_RELATIONS} \n "
227
  return promptForQuery.replace("\\"," ").replace(" "," ").replace("XXXX", " ")
228