refactor chat functions

#39
data_sources/upload_file.py CHANGED
@@ -84,15 +84,18 @@ def process_data_upload(data_file, session_hash):
84
  os.makedirs(dir_path, exist_ok=True)
85
 
86
  connection = sqlite3.connect(f'{dir_path}/data_source.db')
87
- print("Opened database successfully");
88
- print(df.columns)
89
 
90
  df.to_sql('data_source', connection, if_exists='replace', index = False)
 
 
 
 
91
 
92
  connection.commit()
93
  connection.close()
94
 
95
- return ["success","<p style='color:green;text-align:center;font-size:18px;'>Data upload successful</p>"]
96
  except Exception as e:
97
  print("UPLOAD ERROR")
98
  print(e)
 
84
  os.makedirs(dir_path, exist_ok=True)
85
 
86
  connection = sqlite3.connect(f'{dir_path}/data_source.db')
87
+ print("Opened database successfully")
 
88
 
89
  df.to_sql('data_source', connection, if_exists='replace', index = False)
90
+
91
+ cur=connection.execute('select * from data_source')
92
+ columns = [i[0] for i in cur.description]
93
+ print(columns)
94
 
95
  connection.commit()
96
  connection.close()
97
 
98
+ return ["success","<p style='color:green;text-align:center;font-size:18px;'>Data upload successful</p>", columns]
99
  except Exception as e:
100
  print("UPLOAD ERROR")
101
  print(e)
functions/__init__.py CHANGED
@@ -1,9 +1,9 @@
1
  from .query_functions import SQLiteQuery, sqlite_query_func, sql_query_func, doc_db_query_func, graphql_query_func, graphql_schema_query, graphql_csv_query
2
  from .chart_functions import table_generation_func, scatter_chart_generation_func, \
3
  line_chart_generation_func, bar_chart_generation_func, pie_chart_generation_func, histogram_generation_func, scatter_chart_fig
4
- from .chat_functions import sql_example_question_generator, example_question_generator, doc_db_example_question_generator, chatbot_with_fc, sql_chatbot_with_fc, doc_db_chatbot_with_fc, graphql_chatbot_with_fc, graphql_example_question_generator
5
  from .stat_functions import regression_func
6
 
7
  __all__ = ["SQLiteQuery","sqlite_query_func","sql_query_func","doc_db_query_func","graphql_query_func","graphql_schema_query","graphql_csv_query","table_generation_func","scatter_chart_generation_func",
8
  "line_chart_generation_func","bar_chart_generation_func","regression_func", "pie_chart_generation_func", "histogram_generation_func",
9
- "scatter_chart_fig","doc_db_example_question_generator","sql_example_question_generator","example_question_generator","chatbot_with_fc","sql_chatbot_with_fc","doc_db_chatbot_with_fc","graphql_chatbot_with_fc","graphql_example_question_generator"]
 
1
  from .query_functions import SQLiteQuery, sqlite_query_func, sql_query_func, doc_db_query_func, graphql_query_func, graphql_schema_query, graphql_csv_query
2
  from .chart_functions import table_generation_func, scatter_chart_generation_func, \
3
  line_chart_generation_func, bar_chart_generation_func, pie_chart_generation_func, histogram_generation_func, scatter_chart_fig
4
+ from .chat_functions import example_question_generator, chatbot_func
5
  from .stat_functions import regression_func
6
 
7
  __all__ = ["SQLiteQuery","sqlite_query_func","sql_query_func","doc_db_query_func","graphql_query_func","graphql_schema_query","graphql_csv_query","table_generation_func","scatter_chart_generation_func",
8
  "line_chart_generation_func","bar_chart_generation_func","regression_func", "pie_chart_generation_func", "histogram_generation_func",
9
+ "scatter_chart_fig","example_question_generator","chatbot_func"]
functions/chat_functions.py CHANGED
@@ -1,340 +1,161 @@
1
- from utils import TEMP_DIR, message_dict
2
 
3
  from haystack.dataclasses import ChatMessage
4
  from haystack.components.generators.chat import OpenAIChatGenerator
5
 
6
- import sqlite3
7
-
8
  chat_generator = OpenAIChatGenerator(model="gpt-4o")
9
  response = None
10
 
11
- def example_question_generator(session_hash):
12
- example_response = None
13
- example_messages = [
14
- ChatMessage.from_system(
15
- "You are a helpful and knowledgeable agent who has access to an SQLite database which has a table called 'data_source'."
16
- )
17
- ]
18
-
19
- session_path = 'file_upload'
20
-
21
- dir_path = TEMP_DIR / str(session_hash) / str(session_path)
22
- connection = sqlite3.connect(f'{dir_path}/data_source.db')
23
- print("Querying questions");
24
- cur=connection.execute('select * from data_source')
25
- columns = [i[0] for i in cur.description]
26
- print("QUESTION COLUMNS")
27
- print(columns)
28
- cur.close()
29
- connection.close()
30
-
31
- example_messages.append(ChatMessage.from_user(text=f"""We have a SQLite database with the following {columns}.
32
- We also have an AI agent with access to the same database that will be performing data analysis.
33
- Please return an array of seven strings, each one being a question for our data analysis agent
34
- that we can suggest that you believe will be insightful or helpful to a data analysis looking for
35
- data insights. Return nothing more than the array of questions because I need that specific data structure
36
- to process your response. No other response type or data structure will work."""))
37
-
38
- example_response = chat_generator.run(messages=example_messages)
39
-
40
- return example_response["replies"][0].text
41
-
42
- def sql_example_question_generator(session_hash, db_tables, db_name):
43
- example_response = None
44
- example_messages = [
45
- ChatMessage.from_system(
46
- f"You are a helpful and knowledgeable agent who has access to an PostgreSQL database called {db_name}."
47
- )
48
- ]
49
-
50
- example_messages.append(ChatMessage.from_user(text=f"""We have a PostgreSQL database with the following tables: {db_tables}.
51
- We also have an AI agent with access to the same database that will be performing data analysis.
52
- Please return an array of seven strings, each one being a question for our data analysis agent
53
- that we can suggest that you believe will be insightful or helpful to a data analysis looking for
54
- data insights. Return nothing more than the array of questions because I need that specific data structure
55
- to process your response. No other response type or data structure will work."""))
56
-
57
- example_response = chat_generator.run(messages=example_messages)
58
-
59
- return example_response["replies"][0].text
60
-
61
- def doc_db_example_question_generator(session_hash, db_collections, db_name, db_schema):
62
- example_response = None
63
- example_messages = [
64
- ChatMessage.from_system(
65
- f"You are a helpful and knowledgeable agent who has access to an MongoDB NoSQL document database called {db_name}."
66
- )
67
- ]
68
-
69
- example_messages.append(ChatMessage.from_user(text=f"""We have a MongoDB NoSQL document database with the following collections: {db_collections}.
70
- The schema of these collections is: {db_schema}.
71
- We also have an AI agent with access to the same database that will be performing data analysis.
72
- Please return an array of seven strings, each one being a question for our data analysis agent
73
- that we can suggest that you believe will be insightful or helpful to a data analysis looking for
74
- data insights. Return nothing more than the array of questions because I need that specific data structure
75
- to process your response. No other response type or data structure will work."""))
76
-
77
- example_response = chat_generator.run(messages=example_messages)
78
-
79
- return example_response["replies"][0].text
80
-
81
- def graphql_example_question_generator(session_hash, graphql_endpoint, graphql_types):
82
  example_response = None
 
83
  example_messages = [
84
  ChatMessage.from_system(
85
- f"You are a helpful and knowledgeable agent who has access to an GraphQL API endpoint called {graphql_endpoint}."
86
  )
87
  ]
88
 
89
- example_messages.append(ChatMessage.from_user(text=f"""We have a GraphQL API endpoint with the following types: {graphql_types}.
90
- We also have an AI agent with access to the same GraphQL API endpoint that will be performing data analysis.
91
- Please return an array of seven strings, each one being a question for our data analysis agent
92
- that we can suggest that you believe will be insightful or helpful to a data analysis looking for
93
- data insights. Return nothing more than the array of questions because I need that specific data structure
94
- to process your response. No other response type or data structure will work."""))
95
 
96
  example_response = chat_generator.run(messages=example_messages)
97
 
98
  return example_response["replies"][0].text
99
 
100
- def chatbot_with_fc(message, history, session_hash):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  from functions import sqlite_query_func, table_generation_func, regression_func, scatter_chart_generation_func, \
 
102
  line_chart_generation_func,bar_chart_generation_func,pie_chart_generation_func,histogram_generation_func
103
  import tools.tools as tools
104
 
105
- available_functions = {"sql_query_func": sqlite_query_func,"table_generation_func":table_generation_func,
 
 
106
  "line_chart_generation_func":line_chart_generation_func,"bar_chart_generation_func":bar_chart_generation_func,
107
  "scatter_chart_generation_func":scatter_chart_generation_func, "pie_chart_generation_func":pie_chart_generation_func,
108
  "histogram_generation_func":histogram_generation_func,
109
  "regression_func":regression_func }
110
 
111
- session_path = 'file_upload'
112
-
113
- dir_path = TEMP_DIR / str(session_hash) / str(session_path)
114
- connection = sqlite3.connect(f'{dir_path}/data_source.db')
115
- cur=connection.execute('select * from data_source')
116
- columns = [i[0] for i in cur.description]
117
- cur.close()
118
- connection.close()
119
-
120
- if message_dict[session_hash]['file_upload'] != None:
121
- message_dict[session_hash]['file_upload'].append(ChatMessage.from_user(message))
122
- else:
123
- messages = [
124
- ChatMessage.from_system(
125
- f"""You are a helpful and knowledgeable agent who has access to an SQLite database which has a table called 'data_source' that contains the following columns: {columns}.
126
- You also have access to a function, called table_generation_func, that can take a query.csv file generated from our sql query and returns an iframe that we should display in our chat window.
127
- You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
128
- You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
129
- You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
130
- You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
131
- You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
132
- You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our sql query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
133
- Could you please always display the generated charts, tables, and visualizations as part of your output?"""
134
- )
135
- ]
136
- messages.append(ChatMessage.from_user(message))
137
- message_dict[session_hash]['file_upload'] = messages
138
-
139
- response = chat_generator.run(messages=message_dict[session_hash]['file_upload'], generation_kwargs={"tools": tools.data_file_tools_call(session_hash)})
140
-
141
- while True:
142
- # if OpenAI response is a tool call
143
- if response and response["replies"][0].meta["finish_reason"] == "tool_calls" or response["replies"][0].tool_calls:
144
- function_calls = response["replies"][0].tool_calls
145
- for function_call in function_calls:
146
- message_dict[session_hash]['file_upload'].append(ChatMessage.from_assistant(tool_calls=[function_call]))
147
- ## Parse function calling information
148
- function_name = function_call.tool_name
149
- function_args = function_call.arguments
150
-
151
- ## Find the corresponding function and call it with the given arguments
152
- function_to_call = available_functions[function_name]
153
- function_response = function_to_call(**function_args, session_hash=session_hash, session_folder='file_upload')
154
- print(function_name)
155
- ## Append function response to the messages list using `ChatMessage.from_tool`
156
- message_dict[session_hash]['file_upload'].append(ChatMessage.from_tool(tool_result=function_response['reply'], origin=function_call))
157
- response = chat_generator.run(messages=message_dict[session_hash]['file_upload'], generation_kwargs={"tools": tools.data_file_tools_call(session_hash)})
158
-
159
- # Regular Conversation
160
- else:
161
- message_dict[session_hash]['file_upload'].append(response["replies"][0])
162
- break
163
-
164
- return response["replies"][0].text
165
-
166
- def sql_chatbot_with_fc(message, history, session_hash, db_url, db_port, db_user, db_pass, db_name, db_tables):
167
- from functions import sql_query_func, table_generation_func, regression_func, scatter_chart_generation_func, \
168
- line_chart_generation_func,bar_chart_generation_func,pie_chart_generation_func,histogram_generation_func
169
- import tools.tools as tools
170
-
171
- available_functions = {"sql_query_func": sql_query_func,"table_generation_func":table_generation_func,
172
- "line_chart_generation_func":line_chart_generation_func,"bar_chart_generation_func":bar_chart_generation_func,
173
- "scatter_chart_generation_func":scatter_chart_generation_func, "pie_chart_generation_func":pie_chart_generation_func,
174
- "histogram_generation_func":histogram_generation_func,
175
- "regression_func":regression_func }
176
-
177
- if message_dict[session_hash]['sql'] != None:
178
- message_dict[session_hash]['sql'].append(ChatMessage.from_user(message))
179
- else:
180
- messages = [
181
- ChatMessage.from_system(
182
- f"""You are a helpful and knowledgeable agent who has access to an PostgreSQL database which has a series of tables called {db_tables}.
183
- You also have access to a function, called table_generation_func, that can take a query.csv file generated from our sql query and returns an iframe that we should display in our chat window.
184
- You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
185
- You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
186
- You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
187
- You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
188
- You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
189
- You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our sql query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
190
- Could you please always display the generated charts, tables, and visualizations as part of your output?"""
191
- )
192
- ]
193
- messages.append(ChatMessage.from_user(message))
194
- message_dict[session_hash]['sql'] = messages
195
-
196
- response = chat_generator.run(messages=message_dict[session_hash]['sql'], generation_kwargs={"tools": tools.sql_tools_call(db_tables)})
197
-
198
- while True:
199
- # if OpenAI response is a tool call
200
- if response and response["replies"][0].meta["finish_reason"] == "tool_calls" or response["replies"][0].tool_calls:
201
- function_calls = response["replies"][0].tool_calls
202
- for function_call in function_calls:
203
- message_dict[session_hash]['sql'].append(ChatMessage.from_assistant(tool_calls=[function_call]))
204
- ## Parse function calling information
205
- function_name = function_call.tool_name
206
- function_args = function_call.arguments
207
-
208
- ## Find the corresponding function and call it with the given arguments
209
- function_to_call = available_functions[function_name]
210
- function_response = function_to_call(**function_args, session_hash=session_hash, db_url=db_url,
211
- db_port=db_port, db_user=db_user, db_pass=db_pass, db_name=db_name, session_folder='sql')
212
- print(function_name)
213
- ## Append function response to the messages list using `ChatMessage.from_tool`
214
- message_dict[session_hash]['sql'].append(ChatMessage.from_tool(tool_result=function_response['reply'], origin=function_call))
215
- response = chat_generator.run(messages=message_dict[session_hash]['sql'], generation_kwargs={"tools": tools.sql_tools_call(db_tables)})
216
-
217
- # Regular Conversation
218
- else:
219
- message_dict[session_hash]['sql'].append(response["replies"][0])
220
- break
221
-
222
- return response["replies"][0].text
223
-
224
- def doc_db_chatbot_with_fc(message, history, session_hash, db_connection_string, db_name, db_collections, db_schema):
225
- from functions import doc_db_query_func, table_generation_func, regression_func, scatter_chart_generation_func, \
226
- line_chart_generation_func,bar_chart_generation_func,pie_chart_generation_func,histogram_generation_func
227
- import tools.tools as tools
228
-
229
- available_functions = {"doc_db_query_func": doc_db_query_func,"table_generation_func":table_generation_func,
230
- "line_chart_generation_func":line_chart_generation_func,"bar_chart_generation_func":bar_chart_generation_func,
231
- "scatter_chart_generation_func":scatter_chart_generation_func, "pie_chart_generation_func":pie_chart_generation_func,
232
- "histogram_generation_func":histogram_generation_func,
233
- "regression_func":regression_func }
234
-
235
- if message_dict[session_hash]['doc_db'] != None:
236
- message_dict[session_hash]['doc_db'].append(ChatMessage.from_user(message))
237
  else:
238
  messages = [
239
- ChatMessage.from_system(
240
- f"""You are a helpful and knowledgeable agent who has access to a NoSQL MongoDB Document database which has a series of collections called {db_collections}.
241
- The schema of these collections is: {db_schema}.
242
- You also have access to a function, called table_generation_func, that can take a query.csv file generated from our MongoDB query and returns an iframe that we should display in our chat window.
243
- You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
244
- You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
245
- You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
246
- You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
247
- You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
248
- You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our MongoDB query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
249
- Could you please always display the generated charts, tables, and visualizations as part of your output?"""
250
- )
251
  ]
252
  messages.append(ChatMessage.from_user(message))
253
- message_dict[session_hash]['doc_db'] = messages
254
-
255
- response = chat_generator.run(messages=message_dict[session_hash]['doc_db'], generation_kwargs={"tools": tools.doc_db_tools_call(db_collections)})
256
-
257
- while True:
258
- # if OpenAI response is a tool call
259
- if response and response["replies"][0].meta["finish_reason"] == "tool_calls" or response["replies"][0].tool_calls:
260
- function_calls = response["replies"][0].tool_calls
261
- for function_call in function_calls:
262
- message_dict[session_hash]['doc_db'].append(ChatMessage.from_assistant(tool_calls=[function_call]))
263
- ## Parse function calling information
264
- function_name = function_call.tool_name
265
- function_args = function_call.arguments
266
-
267
- ## Find the corresponding function and call it with the given arguments
268
- function_to_call = available_functions[function_name]
269
- function_response = function_to_call(**function_args, session_hash=session_hash, connection_string=db_connection_string,
270
- doc_db_name=db_name, session_folder='doc_db')
271
- print(function_name)
272
- ## Append function response to the messages list using `ChatMessage.from_tool`
273
- message_dict[session_hash]['doc_db'].append(ChatMessage.from_tool(tool_result=function_response['reply'], origin=function_call))
274
- response = chat_generator.run(messages=message_dict[session_hash]['doc_db'], generation_kwargs={"tools": tools.doc_db_tools_call(db_collections)})
275
-
276
- # Regular Conversation
277
- else:
278
- message_dict[session_hash]['doc_db'].append(response["replies"][0])
279
- break
280
-
281
- return response["replies"][0].text
282
-
283
- def graphql_chatbot_with_fc(message, history, session_hash, graphql_api_string, graphql_api_token, graphql_token_header, graphql_types):
284
- from functions import graphql_query_func, graphql_schema_query, graphql_csv_query, table_generation_func, regression_func, scatter_chart_generation_func, \
285
- line_chart_generation_func,bar_chart_generation_func,pie_chart_generation_func,histogram_generation_func
286
- import tools.tools as tools
287
 
288
- available_functions = {"graphql_query_func": graphql_query_func,"graphql_schema_query": graphql_schema_query,"graphql_csv_query": graphql_csv_query,"table_generation_func":table_generation_func,
289
- "line_chart_generation_func":line_chart_generation_func,"bar_chart_generation_func":bar_chart_generation_func,
290
- "scatter_chart_generation_func":scatter_chart_generation_func, "pie_chart_generation_func":pie_chart_generation_func,
291
- "histogram_generation_func":histogram_generation_func,
292
- "regression_func":regression_func }
293
-
294
- if message_dict[session_hash]['graphql'] != None:
295
- message_dict[session_hash]['graphql'].append(ChatMessage.from_user(message))
296
- else:
297
- messages = [
298
- ChatMessage.from_system(
299
- f"""You are a helpful and knowledgeable agent who has access to a GraphQL API which has the following types: {graphql_types}.
300
- We have also saved a schema.json file that contains the entire introspection query that we can use to find out more about each type before making a query.
301
- You also have access to a function, called table_generation_func, that can take a query.csv file generated from our GraphQL API query and returns an iframe that we should display in our chat window.
302
- You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
303
- You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
304
- You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
305
- You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
306
- You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
307
- You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our GraphQL API query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
308
- Could you please always display the generated charts, tables, and visualizations as part of your output?"""
309
- )
310
- ]
311
- messages.append(ChatMessage.from_user(message))
312
- message_dict[session_hash]['graphql'] = messages
313
-
314
- response = chat_generator.run(messages=message_dict[session_hash]['graphql'], generation_kwargs={"tools": tools.graphql_tools_call(graphql_types)})
315
 
316
  while True:
317
  # if OpenAI response is a tool call
318
  if response and response["replies"][0].meta["finish_reason"] == "tool_calls" or response["replies"][0].tool_calls:
319
  function_calls = response["replies"][0].tool_calls
320
  for function_call in function_calls:
321
- message_dict[session_hash]['graphql'].append(ChatMessage.from_assistant(tool_calls=[function_call]))
322
  ## Parse function calling information
323
  function_name = function_call.tool_name
324
  function_args = function_call.arguments
325
 
326
  ## Find the corresponding function and call it with the given arguments
327
  function_to_call = available_functions[function_name]
328
- function_response = function_to_call(**function_args, session_hash=session_hash, graphql_api_string=graphql_api_string,
329
- graphql_api_token=graphql_api_token, graphql_token_header=graphql_token_header, session_folder='graphql')
330
  print(function_name)
331
  ## Append function response to the messages list using `ChatMessage.from_tool`
332
- message_dict[session_hash]['graphql'].append(ChatMessage.from_tool(tool_result=function_response['reply'], origin=function_call))
333
- response = chat_generator.run(messages=message_dict[session_hash]['graphql'], generation_kwargs={"tools": tools.graphql_tools_call(graphql_types)})
334
 
335
  # Regular Conversation
336
  else:
337
- message_dict[session_hash]['graphql'].append(response["replies"][0])
338
  break
339
-
340
  return response["replies"][0].text
 
1
+ from utils import message_dict
2
 
3
  from haystack.dataclasses import ChatMessage
4
  from haystack.components.generators.chat import OpenAIChatGenerator
5
 
 
 
6
  chat_generator = OpenAIChatGenerator(model="gpt-4o")
7
  response = None
8
 
9
+ def example_question_message(data_source, name, titles, schema):
10
+
11
+ example_message_dict = {
12
+ 'file_upload' : ["You are a helpful and knowledgeable agent who has access to an SQLite database which has a table called 'data_source'.",
13
+ f"""We have a SQLite database with the following {titles}.
14
+ We also have an AI agent with access to the same database that will be performing data analysis.
15
+ Please return an array of seven strings, each one being a question for our data analysis agent
16
+ that we can suggest that you believe will be insightful or helpful to a data analysis looking for
17
+ data insights. Return nothing more than the array of questions because I need that specific data structure
18
+ to process your response. No other response type or data structure will work."""],
19
+
20
+ 'sql' : [f"You are a helpful and knowledgeable agent who has access to an MongoDB NoSQL document database called {name}.",
21
+ f"""We have a PostgreSQL database with the following tables: {titles}.
22
+ We also have an AI agent with access to the same database that will be performing data analysis.
23
+ Please return an array of seven strings, each one being a question for our data analysis agent
24
+ that we can suggest that you believe will be insightful or helpful to a data analysis looking for
25
+ data insights. Return nothing more than the array of questions because I need that specific data structure
26
+ to process your response. No other response type or data structure will work."""],
27
+
28
+ 'doc_db' : [f"You are a helpful and knowledgeable agent who has access to an MongoDB NoSQL document database called {name}.",
29
+ f"""We have a MongoDB NoSQL document database with the following collections: {titles}.
30
+ The schema of these collections is: {schema}.
31
+ We also have an AI agent with access to the same database that will be performing data analysis.
32
+ Please return an array of seven strings, each one being a question for our data analysis agent
33
+ that we can suggest that you believe will be insightful or helpful to a data analysis looking for
34
+ data insights. Return nothing more than the array of questions because I need that specific data structure
35
+ to process your response. No other response type or data structure will work."""],
36
+
37
+ 'graphql' : [f"You are a helpful and knowledgeable agent who has access to an GraphQL API endpoint called {name}.",
38
+ f"""We have a GraphQL API endpoint with the following types: {titles}.
39
+ We also have an AI agent with access to the same GraphQL API endpoint that will be performing data analysis.
40
+ Please return an array of seven strings, each one being a question for our data analysis agent
41
+ that we can suggest that you believe will be insightful or helpful to a data analysis looking for
42
+ data insights. Return nothing more than the array of questions because I need that specific data structure
43
+ to process your response. No other response type or data structure will work."""]
44
+
45
+ }
46
+
47
+ return example_message_dict[data_source]
48
+
49
+ def example_question_generator(session_hash, data_source, name, titles, schema):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  example_response = None
51
+ example_message_list = example_question_message(data_source, name, titles, schema)
52
  example_messages = [
53
  ChatMessage.from_system(
54
+ example_message_list[0]
55
  )
56
  ]
57
 
58
+ example_messages.append(ChatMessage.from_user(text=example_message_list[1]))
 
 
 
 
 
59
 
60
  example_response = chat_generator.run(messages=example_messages)
61
 
62
  return example_response["replies"][0].text
63
 
64
+ def system_message(data_source, titles, schema=""):
65
+
66
+ system_message_dict = {
67
+ 'file_upload' : f"""You are a helpful and knowledgeable agent who has access to an SQLite database which has a table called 'data_source' that contains the following columns: {titles}.
68
+ You also have access to a function, called table_generation_func, that can take a query.csv file generated from our sql query and returns an iframe that we should display in our chat window.
69
+ You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
70
+ You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
71
+ You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
72
+ You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
73
+ You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
74
+ You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our sql query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
75
+ Could you please always display the generated charts, tables, and visualizations as part of your output?""",
76
+
77
+ 'sql' : f"""You are a helpful and knowledgeable agent who has access to an PostgreSQL database which has a series of tables called {titles}.
78
+ You also have access to a function, called table_generation_func, that can take a query.csv file generated from our sql query and returns an iframe that we should display in our chat window.
79
+ You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
80
+ You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
81
+ You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
82
+ You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
83
+ You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our sql query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
84
+ You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our sql query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
85
+ Could you please always display the generated charts, tables, and visualizations as part of your output?""",
86
+
87
+ 'doc_db' : f"""You are a helpful and knowledgeable agent who has access to a NoSQL MongoDB Document database which has a series of collections called {titles}.
88
+ The schema of these collections is: {schema}.
89
+ You also have access to a function, called table_generation_func, that can take a query.csv file generated from our MongoDB query and returns an iframe that we should display in our chat window.
90
+ You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
91
+ You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
92
+ You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
93
+ You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
94
+ You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our MongoDB query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
95
+ You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our MongoDB query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
96
+ Could you please always display the generated charts, tables, and visualizations as part of your output?""",
97
+
98
+ 'graphql' : f"""You are a helpful and knowledgeable agent who has access to a GraphQL API which has the following types: {titles}.
99
+ We have also saved a schema.json file that contains the entire introspection query that we can use to find out more about each type before making a query.
100
+ You also have access to a function, called table_generation_func, that can take a query.csv file generated from our GraphQL API query and returns an iframe that we should display in our chat window.
101
+ You also have access to a scatter plot function, called scatter_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a scatter plot and returns an iframe that we should display in our chat window.
102
+ You also have access to a line chart function, called line_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a line chart and returns an iframe that we should display in our chat window.
103
+ You also have access to a bar graph function, called line_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a bar graph and returns an iframe that we should display in our chat window.
104
+ You also have access to a pie chart function, called pie_chart_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a pie chart and returns an iframe that we should display in our chat window.
105
+ You also have access to a histogram function, called histogram_generation_func, that can take a query.csv file generated from our GraphQL API query and uses plotly dictionaries to generate a histogram and returns an iframe that we should display in our chat window.
106
+ You also have access to a linear regression function, called regression_func, that can take a query.csv file generated from our GraphQL API query and a list of column names for our independent and dependent variables and return a regression data string and a regression chart which is returned as an iframe.
107
+ Could you please always display the generated charts, tables, and visualizations as part of your output?"""
108
+
109
+ }
110
+
111
+ return system_message_dict[data_source]
112
+
113
+ def chatbot_func(message, history, session_hash, data_source, titles, schema, *args):
114
  from functions import sqlite_query_func, table_generation_func, regression_func, scatter_chart_generation_func, \
115
+ sql_query_func, doc_db_query_func, graphql_query_func, graphql_schema_query, graphql_csv_query, \
116
  line_chart_generation_func,bar_chart_generation_func,pie_chart_generation_func,histogram_generation_func
117
  import tools.tools as tools
118
 
119
+ available_functions = {"sqlite_query_func": sqlite_query_func,"sql_query_func": sql_query_func,"doc_db_query_func": doc_db_query_func,
120
+ "graphql_query_func": graphql_query_func,"graphql_schema_query": graphql_schema_query,"graphql_csv_query": graphql_csv_query,
121
+ "table_generation_func":table_generation_func,
122
  "line_chart_generation_func":line_chart_generation_func,"bar_chart_generation_func":bar_chart_generation_func,
123
  "scatter_chart_generation_func":scatter_chart_generation_func, "pie_chart_generation_func":pie_chart_generation_func,
124
  "histogram_generation_func":histogram_generation_func,
125
  "regression_func":regression_func }
126
 
127
+ if message_dict[session_hash][data_source] != None:
128
+ message_dict[session_hash][data_source].append(ChatMessage.from_user(message))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  else:
130
  messages = [
131
+ ChatMessage.from_system(system_message(data_source, titles, schema))
 
 
 
 
 
 
 
 
 
 
 
132
  ]
133
  messages.append(ChatMessage.from_user(message))
134
+ message_dict[session_hash][data_source] = messages
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
+ response = chat_generator.run(messages=message_dict[session_hash][data_source], generation_kwargs={"tools": tools.tools_call(session_hash, data_source, titles)})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
  while True:
139
  # if OpenAI response is a tool call
140
  if response and response["replies"][0].meta["finish_reason"] == "tool_calls" or response["replies"][0].tool_calls:
141
  function_calls = response["replies"][0].tool_calls
142
  for function_call in function_calls:
143
+ message_dict[session_hash][data_source].append(ChatMessage.from_assistant(tool_calls=[function_call]))
144
  ## Parse function calling information
145
  function_name = function_call.tool_name
146
  function_args = function_call.arguments
147
 
148
  ## Find the corresponding function and call it with the given arguments
149
  function_to_call = available_functions[function_name]
150
+ function_response = function_to_call(**function_args, session_hash=session_hash, session_folder=data_source, args=args)
 
151
  print(function_name)
152
  ## Append function response to the messages list using `ChatMessage.from_tool`
153
+ message_dict[session_hash][data_source].append(ChatMessage.from_tool(tool_result=function_response['reply'], origin=function_call))
154
+ response = chat_generator.run(messages=message_dict[session_hash][data_source], generation_kwargs={"tools": tools.tools_call(session_hash, data_source, titles)})
155
 
156
  # Regular Conversation
157
  else:
158
+ message_dict[session_hash][data_source].append(response["replies"][0])
159
  break
160
+
161
  return response["replies"][0].text
functions/query_functions.py CHANGED
@@ -81,8 +81,8 @@ class PostgreSQLQuery:
81
 
82
 
83
 
84
- def sql_query_func(queries: List[str], session_hash, db_url, db_port, db_user, db_pass, db_name, **kwargs):
85
- sql_query = PostgreSQLQuery(db_url, db_port, db_user, db_pass, db_name)
86
  try:
87
  result = sql_query.run(queries, session_hash)
88
  print("RESULT")
@@ -150,8 +150,8 @@ class DocDBQuery:
150
 
151
 
152
 
153
- def doc_db_query_func(aggregation_pipeline: List[str], db_collection: AnyStr, session_hash, connection_string, doc_db_name, **kwargs):
154
- doc_db_query = DocDBQuery(connection_string, doc_db_name)
155
  try:
156
  result = doc_db_query.run(aggregation_pipeline, db_collection, session_hash)
157
  print("RESULT")
@@ -206,10 +206,10 @@ class GraphQLQuery:
206
 
207
 
208
 
209
- def graphql_query_func(graphql_query: AnyStr, session_hash, graphql_api_string, graphql_api_token, graphql_token_header, **kwargs):
210
  graphql_object = GraphQLQuery()
211
  try:
212
- result = graphql_object.run(graphql_query, graphql_api_string, graphql_api_token, graphql_token_header, session_hash)
213
  print("RESULT")
214
  if len(result["results"][0]) > 1000:
215
  print("QUERY TOO LARGE")
 
81
 
82
 
83
 
84
+ def sql_query_func(queries: List[str], session_hash, args, **kwargs):
85
+ sql_query = PostgreSQLQuery(args[0], args[1], args[2], args[3], args[4])
86
  try:
87
  result = sql_query.run(queries, session_hash)
88
  print("RESULT")
 
150
 
151
 
152
 
153
+ def doc_db_query_func(aggregation_pipeline: List[str], db_collection: AnyStr, session_hash, args, **kwargs):
154
+ doc_db_query = DocDBQuery(args[0], args[1])
155
  try:
156
  result = doc_db_query.run(aggregation_pipeline, db_collection, session_hash)
157
  print("RESULT")
 
206
 
207
 
208
 
209
+ def graphql_query_func(graphql_query: AnyStr, session_hash, args, **kwargs):
210
  graphql_object = GraphQLQuery()
211
  try:
212
+ result = graphql_object.run(graphql_query, args[0], args[1], args[2], session_hash)
213
  print("RESULT")
214
  if len(result["results"][0]) > 1000:
215
  print("QUERY TOO LARGE")
templates/data_file.py CHANGED
@@ -1,5 +1,5 @@
1
  import gradio as gr
2
- from functions import example_question_generator, chatbot_with_fc
3
  from data_sources import process_data_upload
4
  from utils import message_dict
5
  import ast
@@ -97,7 +97,7 @@ with gr.Blocks() as demo:
97
  ]
98
  else:
99
  try:
100
- generated_examples = ast.literal_eval(example_question_generator(request.session_hash))
101
  example_questions = [
102
  ["Describe the dataset"]
103
  ]
@@ -111,16 +111,19 @@ with gr.Blocks() as demo:
111
  ["List the columns in the dataset"],
112
  ["What could this data be used for?"],
113
  ]
114
- parameters = gr.Textbox(visible=False, value=request.session_hash)
 
 
 
115
  bot = gr.Chatbot(type='messages', label="CSV Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
116
  chat = gr.ChatInterface(
117
- fn=chatbot_with_fc,
118
  type='messages',
119
  chatbot=bot,
120
  title="Chat with your data file",
121
  concurrency_limit=None,
122
  examples=example_questions,
123
- additional_inputs=parameters
124
  )
125
 
126
  def process_upload(upload_value, session_hash):
 
1
  import gradio as gr
2
+ from functions import example_question_generator, chatbot_func
3
  from data_sources import process_data_upload
4
  from utils import message_dict
5
  import ast
 
97
  ]
98
  else:
99
  try:
100
+ generated_examples = ast.literal_eval(example_question_generator(request.session_hash, 'file_upload', '', process_message[1], ''))
101
  example_questions = [
102
  ["Describe the dataset"]
103
  ]
 
111
  ["List the columns in the dataset"],
112
  ["What could this data be used for?"],
113
  ]
114
+ session_hash = gr.Textbox(visible=False, value=request.session_hash)
115
+ data_source = gr.Textbox(visible=False, value='file_upload')
116
+ schema = gr.Textbox(visible=False, value='')
117
+ titles = gr.Textbox(value=process_message[1], interactive=False, visible=False)
118
  bot = gr.Chatbot(type='messages', label="CSV Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
119
  chat = gr.ChatInterface(
120
+ fn=chatbot_func,
121
  type='messages',
122
  chatbot=bot,
123
  title="Chat with your data file",
124
  concurrency_limit=None,
125
  examples=example_questions,
126
+ additional_inputs=[session_hash, data_source, titles, schema]
127
  )
128
 
129
  def process_upload(upload_value, session_hash):
templates/doc_db.py CHANGED
@@ -1,6 +1,6 @@
1
  import ast
2
  import gradio as gr
3
- from functions import doc_db_example_question_generator, doc_db_chatbot_with_fc
4
  from data_sources import connect_doc_db
5
  from utils import message_dict
6
 
@@ -59,7 +59,7 @@ with gr.Blocks() as demo:
59
  ]
60
  else:
61
  try:
62
- generated_examples = ast.literal_eval(doc_db_example_question_generator(request.session_hash, process_message[2], doc_db_name, process_message[3]))
63
  example_questions = [
64
  ["Describe the dataset"]
65
  ]
@@ -76,17 +76,18 @@ with gr.Blocks() as demo:
76
  session_hash = gr.Textbox(visible=False, value=request.session_hash)
77
  db_connection_string = gr.Textbox(visible=False, value=connection_login_value)
78
  db_name = gr.Textbox(visible=False, value=doc_db_name)
79
- db_collections = gr.Textbox(value=process_message[2], interactive=False, label="DB Collections")
80
- db_schema = gr.Textbox(visible=False, value=process_message[3])
 
81
  bot = gr.Chatbot(type='messages', label="DocDB Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
82
  chat = gr.ChatInterface(
83
- fn=doc_db_chatbot_with_fc,
84
  type='messages',
85
  chatbot=bot,
86
  title="Chat with your Database",
87
  examples=example_questions,
88
  concurrency_limit=None,
89
- additional_inputs=[session_hash, db_connection_string, db_name, db_collections,db_schema]
90
  )
91
 
92
  def process_doc_db(connection_string, nosql_db_name, session_hash):
 
1
  import ast
2
  import gradio as gr
3
+ from functions import example_question_generator, chatbot_func
4
  from data_sources import connect_doc_db
5
  from utils import message_dict
6
 
 
59
  ]
60
  else:
61
  try:
62
+ generated_examples = ast.literal_eval(example_question_generator(request.session_hash, 'graphql', doc_db_name, process_message[2], process_message[3]))
63
  example_questions = [
64
  ["Describe the dataset"]
65
  ]
 
76
  session_hash = gr.Textbox(visible=False, value=request.session_hash)
77
  db_connection_string = gr.Textbox(visible=False, value=connection_login_value)
78
  db_name = gr.Textbox(visible=False, value=doc_db_name)
79
+ titles = gr.Textbox(value=process_message[2], interactive=False, label="DB Collections")
80
+ data_source = gr.Textbox(visible=False, value='doc_db')
81
+ schema = gr.Textbox(visible=False, value=process_message[3])
82
  bot = gr.Chatbot(type='messages', label="DocDB Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
83
  chat = gr.ChatInterface(
84
+ fn=chatbot_func,
85
  type='messages',
86
  chatbot=bot,
87
  title="Chat with your Database",
88
  examples=example_questions,
89
  concurrency_limit=None,
90
+ additional_inputs=[session_hash, data_source, titles, schema, db_connection_string, db_name]
91
  )
92
 
93
  def process_doc_db(connection_string, nosql_db_name, session_hash):
templates/graphql.py CHANGED
@@ -1,6 +1,6 @@
1
  import ast
2
  import gradio as gr
3
- from functions import graphql_example_question_generator, graphql_chatbot_with_fc
4
  from data_sources import connect_graphql
5
  from utils import message_dict
6
 
@@ -69,7 +69,7 @@ with gr.Blocks() as demo:
69
  ]
70
  else:
71
  try:
72
- generated_examples = ast.literal_eval(graphql_example_question_generator(request.session_hash, graphql_url, process_message[2]))
73
  example_questions = [
74
  ["Describe the dataset"]
75
  ]
@@ -87,16 +87,18 @@ with gr.Blocks() as demo:
87
  graphql_api_string = gr.Textbox(visible=False, value=graphql_url)
88
  graphql_api_token = gr.Textbox(visible=False, value=api_token)
89
  graphql_token_header = gr.Textbox(visible=False, value=api_token_header_name)
90
- graphql_types = gr.Textbox(value=process_message[2], interactive=False, label="GraphQL Types")
 
 
91
  bot = gr.Chatbot(type='messages', label="GraphQL Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
92
  chat = gr.ChatInterface(
93
- fn=graphql_chatbot_with_fc,
94
  type='messages',
95
  chatbot=bot,
96
  title="Chat with your Graphql API",
97
  examples=example_questions,
98
  concurrency_limit=None,
99
- additional_inputs=[session_hash, graphql_api_string, graphql_api_token, graphql_token_header, graphql_types]
100
  )
101
 
102
  def process_graphql(graphql_url, api_token, api_token_header_name, session_hash):
 
1
  import ast
2
  import gradio as gr
3
+ from functions import example_question_generator, chatbot_func
4
  from data_sources import connect_graphql
5
  from utils import message_dict
6
 
 
69
  ]
70
  else:
71
  try:
72
+ generated_examples = ast.literal_eval(example_question_generator(request.session_hash, 'graphql', graphql_url, process_message[2], ''))
73
  example_questions = [
74
  ["Describe the dataset"]
75
  ]
 
87
  graphql_api_string = gr.Textbox(visible=False, value=graphql_url)
88
  graphql_api_token = gr.Textbox(visible=False, value=api_token)
89
  graphql_token_header = gr.Textbox(visible=False, value=api_token_header_name)
90
+ titles = gr.Textbox(value=process_message[2], interactive=False, label="GraphQL Types")
91
+ data_source = gr.Textbox(visible=False, value='graphql')
92
+ schema = gr.Textbox(visible=False, value='')
93
  bot = gr.Chatbot(type='messages', label="GraphQL Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
94
  chat = gr.ChatInterface(
95
+ fn=chatbot_func,
96
  type='messages',
97
  chatbot=bot,
98
  title="Chat with your Graphql API",
99
  examples=example_questions,
100
  concurrency_limit=None,
101
+ additional_inputs=[session_hash, data_source, titles, schema, graphql_api_string, graphql_api_token, graphql_token_header]
102
  )
103
 
104
  def process_graphql(graphql_url, api_token, api_token_header_name, session_hash):
templates/sql_db.py CHANGED
@@ -1,6 +1,6 @@
1
  import ast
2
  import gradio as gr
3
- from functions import sql_example_question_generator, sql_chatbot_with_fc
4
  from data_sources import connect_sql_db
5
  from utils import message_dict
6
 
@@ -55,7 +55,7 @@ with gr.Blocks() as demo:
55
  ]
56
  else:
57
  try:
58
- generated_examples = ast.literal_eval(sql_example_question_generator(request.session_hash, process_message[2], sql_db_name))
59
  example_questions = [
60
  ["Describe the dataset"]
61
  ]
@@ -75,16 +75,18 @@ with gr.Blocks() as demo:
75
  db_user = gr.Textbox(visible=False, value=sql_user)
76
  db_pass = gr.Textbox(visible=False, value=sql_pass)
77
  db_name = gr.Textbox(visible=False, value=sql_db_name)
78
- db_tables = gr.Textbox(value=process_message[2], interactive=False, label="SQL Tables")
 
 
79
  bot = gr.Chatbot(type='messages', label="SQL DB Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
80
  chat = gr.ChatInterface(
81
- fn=sql_chatbot_with_fc,
82
  type='messages',
83
  chatbot=bot,
84
  title="Chat with your Database",
85
  examples=example_questions,
86
  concurrency_limit=None,
87
- additional_inputs=[session_hash, db_url, db_port, db_user, db_pass, db_name, db_tables]
88
  )
89
 
90
  def process_sql_db(url, sql_user, sql_port, sql_pass, sql_db_name, session_hash):
 
1
  import ast
2
  import gradio as gr
3
+ from functions import example_question_generator, chatbot_func
4
  from data_sources import connect_sql_db
5
  from utils import message_dict
6
 
 
55
  ]
56
  else:
57
  try:
58
+ generated_examples = ast.literal_eval(example_question_generator(request.session_hash, 'sql', sql_db_name, process_message[2], ""))
59
  example_questions = [
60
  ["Describe the dataset"]
61
  ]
 
75
  db_user = gr.Textbox(visible=False, value=sql_user)
76
  db_pass = gr.Textbox(visible=False, value=sql_pass)
77
  db_name = gr.Textbox(visible=False, value=sql_db_name)
78
+ titles = gr.Textbox(value=process_message[2], interactive=False, label="SQL Tables")
79
+ data_source = gr.Textbox(visible=False, value='sql')
80
+ schema = gr.Textbox(visible=False, value='')
81
  bot = gr.Chatbot(type='messages', label="SQL DB Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
82
  chat = gr.ChatInterface(
83
+ fn=chatbot_func,
84
  type='messages',
85
  chatbot=bot,
86
  title="Chat with your Database",
87
  examples=example_questions,
88
  concurrency_limit=None,
89
+ additional_inputs=[session_hash, data_source, titles, schema, db_url, db_port, db_user, db_pass, db_name]
90
  )
91
 
92
  def process_sql_db(url, sql_user, sql_port, sql_pass, sql_db_name, session_hash):
tools/tools.py CHANGED
@@ -1,187 +1,149 @@
1
- import sqlite3
2
- import psycopg2
3
  from .stats_tools import stats_tools
4
  from .chart_tools import chart_tools
5
- from utils import TEMP_DIR
6
 
7
- def data_file_tools_call(session_hash):
8
- dir_path = TEMP_DIR / str(session_hash)
9
- connection = sqlite3.connect(f'{dir_path}/file_upload/data_source.db')
10
- print("Querying Database in Tools.py");
11
- cur=connection.execute('select * from data_source')
12
- columns = [i[0] for i in cur.description]
13
- print("COLUMNS 2")
14
- print(columns)
15
- cur.close()
16
- connection.close()
17
 
18
- column_string = (columns[:625] + '..') if len(columns) > 625 else columns
19
 
20
- tools_calls = [
21
- {
22
- "type": "function",
23
- "function": {
24
- "name": "sql_query_func",
25
- "description": f"""This is a tool useful to query a SQLite table called 'data_source' with the following Columns: {column_string}.
26
- There may also be more columns in the table if the number of columns is too large to process.
27
- This function also saves the results of the query to csv file called query.csv.""",
28
- "parameters": {
29
- "type": "object",
30
- "properties": {
31
- "queries": {
32
- "type": "array",
33
- "description": "The query to use in the search. Infer this from the user's message. It should be a question or a statement",
34
- "items": {
35
- "type": "string",
36
- }
37
- }
 
 
 
 
38
  },
39
- "required": ["queries"],
40
  },
41
- },
42
- },
43
- ]
44
-
45
- tools_calls.extend(chart_tools)
46
- tools_calls.extend(stats_tools)
47
-
48
- return tools_calls
49
-
50
- def sql_tools_call(db_tables):
51
-
52
- table_string = (db_tables[:625] + '..') if len(db_tables) > 625 else db_tables
53
-
54
- tools_calls = [
55
- {
56
- "type": "function",
57
- "function": {
58
- "name": "sql_query_func",
59
- "description": f"""This is a tool useful to query a PostgreSQL database with the following tables, {table_string}.
60
- There may also be more tables in the database if the number of tables is too large to process.
61
- This function also saves the results of the query to csv file called query.csv.""",
62
- "parameters": {
63
- "type": "object",
64
- "properties": {
65
- "queries": {
66
- "type": "array",
67
- "description": "The PostgreSQL query to use in the search. Infer this from the user's message. It should be a question or a statement",
68
- "items": {
69
- "type": "string",
70
  }
71
- }
 
72
  },
73
- "required": ["queries"],
74
  },
75
  },
76
- },
77
- ]
78
-
79
- tools_calls.extend(chart_tools)
80
- tools_calls.extend(stats_tools)
81
-
82
- return tools_calls
83
-
84
- def doc_db_tools_call(db_collections):
85
-
86
- collection_string = (db_collections[:625] + '..') if len(db_collections) > 625 else db_collections
87
-
88
- tools_calls = [
89
- {
90
- "type": "function",
91
- "function": {
92
- "name": "doc_db_query_func",
93
- "description": f"""This is a tool useful to build an aggregation pipeline to query a MongoDB NoSQL document database with the following collections, {collection_string}.
94
- There may also be more collections in the database if the number of tables is too large to process.
95
- This function also saves the results of the query to a csv file called query.csv.""",
96
- "parameters": {
97
- "type": "object",
98
- "properties": {
99
- "aggregation_pipeline": {
100
- "type": "string",
101
- "description": "The MongoDB aggregation pipeline to use in the search. Infer this from the user's message. It should be a question or a statement."
102
  },
103
- "db_collection": {
104
- "type": "string",
105
- "description": "The MongoDB collection to use in the search. Infer this from the user's message. It should be a question or a statement.",
106
- }
107
  },
108
- "required": ["aggregation_pipeline","db_collection"],
109
  },
110
  },
111
- },
112
- ]
113
-
114
- tools_calls.extend(chart_tools)
115
- tools_calls.extend(stats_tools)
116
-
117
- return tools_calls
118
-
119
- def graphql_tools_call(graphql_types):
120
-
121
- types_string = (graphql_types[:625] + '..') if len(graphql_types) > 625 else graphql_types
122
-
123
- tools_calls = [
124
- {
125
- "type": "function",
126
- "function": {
127
- "name": "graphql_query_func",
128
- "description": f"""This is a tool useful to build a GraphQL query for a GraphQL API endpoint with the following types, {types_string}.
129
- There may also be more types in the GraphQL endpoint if the number of types is too large to process.
130
- This function also saves the results of the query to a csv file called query.csv.""",
131
- "parameters": {
132
- "type": "object",
133
- "properties": {
134
- "graphql_query": {
135
- "type": "string",
136
- "description": "The GraphQL query to use in the search. Infer this from the user's message. It should be a question or a statement."
137
- }
138
  },
139
- "required": ["graphql_query"],
140
  },
141
  },
142
- },
143
- {
144
- "type": "function",
145
- "function": {
146
- "name": "graphql_schema_query",
147
- "description": f"""This is a tool useful to query a GraphQL type and receive back information about its schema. This is useful because
148
- the GraphQL introspection query is too large to be ingested all at once and this allows us to query the schema one type at a time to
149
- view it in manageable bites. You may realize after viewing the schema, that the type you selected was not appropriate for the question
150
- you are attempting answer. You may then query additional types to find the appropriate types to use for your GraphQL API query.""",
151
- "parameters": {
152
- "type": "object",
153
- "properties": {
154
- "graphql_type": {
155
- "type": "string",
156
- "description": "The GraphQL type that we want to view the schema of in order to make the proper query with our graphql_query_func. Infer this from the user's message. It should be a question or a statement."
157
- }
 
158
  },
159
- "required": ["graphql_type"],
160
  },
161
  },
162
- },
163
- {
164
- "type": "function",
165
- "function": {
166
- "name": "graphql_csv_query",
167
- "description": f"""This is a tool useful to SQL query our query.csv file that is generated from our GraphQL query. This is useful in a situation
168
- where the results of the GraphQL query need additional querying to answer the user question. The query.csv file is converted to a Pandas dataframe
169
- and we query that dataframe with SQL on a table called 'query' before converting it back to a csv file.""",
170
- "parameters": {
171
- "type": "object",
172
- "properties": {
173
- "csv_query": {
174
- "type": "string",
175
- "description": "The pandas dataframe SQL query to use in the search. The table that we query is named 'query'. Infer this from the user's message. It should be a question or a statement"
176
- }
 
177
  },
178
- "required": ["csv_query"],
179
  },
180
  },
181
- },
182
- ]
 
 
183
 
184
- tools_calls.extend(chart_tools)
185
- tools_calls.extend(stats_tools)
186
 
187
- return tools_calls
 
 
 
1
  from .stats_tools import stats_tools
2
  from .chart_tools import chart_tools
 
3
 
4
+ def tools_call(session_hash, data_source, titles):
 
 
 
 
 
 
 
 
 
5
 
6
+ titles_string = (titles[:625] + '..') if len(titles) > 625 else titles
7
 
8
+ tools_calls = {
9
+ 'file_upload' : [
10
+ {
11
+ "type": "function",
12
+ "function": {
13
+ "name": "sqlite_query_func",
14
+ "description": f"""This is a tool useful to query a SQLite table called 'data_source' with the following Columns: {titles_string}.
15
+ There may also be more columns in the table if the number of columns is too large to process.
16
+ This function also saves the results of the query to csv file called query.csv.""",
17
+ "parameters": {
18
+ "type": "object",
19
+ "properties": {
20
+ "queries": {
21
+ "type": "array",
22
+ "description": "The query to use in the search. Infer this from the user's message. It should be a question or a statement",
23
+ "items": {
24
+ "type": "string",
25
+ }
26
+ }
27
+ },
28
+ "required": ["queries"],
29
+ },
30
  },
 
31
  },
32
+ ],
33
+ 'sql' : [
34
+ {
35
+ "type": "function",
36
+ "function": {
37
+ "name": "sql_query_func",
38
+ "description": f"""This is a tool useful to query a PostgreSQL database with the following tables, {titles_string}.
39
+ There may also be more tables in the database if the number of tables is too large to process.
40
+ This function also saves the results of the query to csv file called query.csv.""",
41
+ "parameters": {
42
+ "type": "object",
43
+ "properties": {
44
+ "queries": {
45
+ "type": "array",
46
+ "description": "The PostgreSQL query to use in the search. Infer this from the user's message. It should be a question or a statement",
47
+ "items": {
48
+ "type": "string",
49
+ }
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
+ },
52
+ "required": ["queries"],
53
  },
 
54
  },
55
  },
56
+ ],
57
+ 'doc_db' : [
58
+ {
59
+ "type": "function",
60
+ "function": {
61
+ "name": "doc_db_query_func",
62
+ "description": f"""This is a tool useful to build an aggregation pipeline to query a MongoDB NoSQL document database with the following collections, {titles_string}.
63
+ There may also be more collections in the database if the number of tables is too large to process.
64
+ This function also saves the results of the query to a csv file called query.csv.""",
65
+ "parameters": {
66
+ "type": "object",
67
+ "properties": {
68
+ "aggregation_pipeline": {
69
+ "type": "string",
70
+ "description": "The MongoDB aggregation pipeline to use in the search. Infer this from the user's message. It should be a question or a statement."
71
+ },
72
+ "db_collection": {
73
+ "type": "string",
74
+ "description": "The MongoDB collection to use in the search. Infer this from the user's message. It should be a question or a statement.",
75
+ }
 
 
 
 
 
 
76
  },
77
+ "required": ["aggregation_pipeline","db_collection"],
 
 
 
78
  },
 
79
  },
80
  },
81
+ ],
82
+ 'graphql' : [
83
+ {
84
+ "type": "function",
85
+ "function": {
86
+ "name": "graphql_query_func",
87
+ "description": f"""This is a tool useful to build a GraphQL query for a GraphQL API endpoint with the following types, {titles_string}.
88
+ There may also be more types in the GraphQL endpoint if the number of types is too large to process.
89
+ This function also saves the results of the query to a csv file called query.csv.""",
90
+ "parameters": {
91
+ "type": "object",
92
+ "properties": {
93
+ "graphql_query": {
94
+ "type": "string",
95
+ "description": "The GraphQL query to use in the search. Infer this from the user's message. It should be a question or a statement."
96
+ }
97
+ },
98
+ "required": ["graphql_query"],
 
 
 
 
 
 
 
 
 
99
  },
 
100
  },
101
  },
102
+ {
103
+ "type": "function",
104
+ "function": {
105
+ "name": "graphql_schema_query",
106
+ "description": f"""This is a tool useful to query a GraphQL type and receive back information about its schema. This is useful because
107
+ the GraphQL introspection query is too large to be ingested all at once and this allows us to query the schema one type at a time to
108
+ view it in manageable bites. You may realize after viewing the schema, that the type you selected was not appropriate for the question
109
+ you are attempting answer. You may then query additional types to find the appropriate types to use for your GraphQL API query.""",
110
+ "parameters": {
111
+ "type": "object",
112
+ "properties": {
113
+ "graphql_type": {
114
+ "type": "string",
115
+ "description": "The GraphQL type that we want to view the schema of in order to make the proper query with our graphql_query_func. Infer this from the user's message. It should be a question or a statement."
116
+ }
117
+ },
118
+ "required": ["graphql_type"],
119
  },
 
120
  },
121
  },
122
+ {
123
+ "type": "function",
124
+ "function": {
125
+ "name": "graphql_csv_query",
126
+ "description": f"""This is a tool useful to SQL query our query.csv file that is generated from our GraphQL query. This is useful in a situation
127
+ where the results of the GraphQL query need additional querying to answer the user question. The query.csv file is converted to a Pandas dataframe
128
+ and we query that dataframe with SQL on a table called 'query' before converting it back to a csv file.""",
129
+ "parameters": {
130
+ "type": "object",
131
+ "properties": {
132
+ "csv_query": {
133
+ "type": "string",
134
+ "description": "The pandas dataframe SQL query to use in the search. The table that we query is named 'query'. Infer this from the user's message. It should be a question or a statement"
135
+ }
136
+ },
137
+ "required": ["csv_query"],
138
  },
 
139
  },
140
  },
141
+ ]
142
+ }
143
+
144
+ tools = tools_calls[data_source]
145
 
146
+ tools.extend(chart_tools)
147
+ tools.extend(stats_tools)
148
 
149
+ return tools