Redmind commited on
Commit
f152261
·
verified ·
1 Parent(s): 8b1afad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +451 -96
app.py CHANGED
@@ -11,18 +11,20 @@ import time
11
  import shutil
12
  import json
13
  import nltk
14
- #commenting audio related code based on Arun's input
 
 
15
  # audio package
16
- """import speech_recognition as sr
17
  from pydub import AudioSegment
18
- from pydub.playback import play"""
19
- # Commenting SMTP code since HFSpaces doesn't support it
20
  # email library
21
- """import smtplib, ssl
22
  from email.mime.multipart import MIMEMultipart
23
  from email.mime.text import MIMEText
24
  from email.mime.base import MIMEBase
25
- from email import encoders"""
26
  # langchain
27
  from langchain_core.prompts import ChatPromptTemplate
28
  from langchain_core.output_parsers import StrOutputParser
@@ -34,12 +36,14 @@ from langchain_community.utilities import SQLDatabase
34
  from langchain.agents import create_tool_calling_agent, AgentExecutor, Tool
35
  from langchain.text_splitter import RecursiveCharacterTextSplitter
36
  from langchain.tools import StructuredTool
37
- from langchain.pydantic_v1 import BaseModel, Field
 
38
  from PyPDF2 import PdfReader
39
  from nltk.tokenize import sent_tokenize
40
  from datetime import datetime
41
  from sqlalchemy import create_engine
42
  from sqlalchemy.sql import text
 
43
 
44
  # pandas
45
  import pandas as pd
@@ -64,6 +68,15 @@ import threading
64
  from mailjet_rest import Client
65
  import base64
66
 
 
 
 
 
 
 
 
 
 
67
  # Define global variables for managing the thread and current_event
68
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
69
  current_event = None
@@ -74,19 +87,25 @@ os.environ["LANGFUSE_PUBLIC_KEY"] = os.getenv("LANGFUSE_PUBLIC_KEY")
74
  os.environ["LANGFUSE_SECRET_KEY"] = os.getenv("LANGFUSE_SECRET_KEY")
75
  os.environ["LANGFUSE_HOST"] = os.getenv("LANGFUSE_HOST")
76
 
 
 
 
 
 
 
77
  langfuse_handler = CallbackHandler()
78
  langfuse_handler.auth_check() # Optional: Checks if the authentication is successful
79
 
80
  nltk.download('punkt')
81
 
82
- open_api_key_token = os.getenv("OPEN_AI_API")
83
 
84
  os.environ['OPENAI_API_KEY'] = open_api_key_token
85
  pdf_path = "Inbound.pdf"
86
 
87
  db_uri = os.getenv("POSTGRESQL_CONNECTION")
88
- # Database setup
89
 
 
90
  db = SQLDatabase.from_uri(db_uri)
91
 
92
  user_email = ""
@@ -94,6 +113,7 @@ warehouse_name = ""
94
  warehouse_id = ""
95
  # Today's date to be populated in inventory API
96
  inventory_date = datetime.today().strftime('%Y-%m-%d')
 
97
  apis = [
98
  # fetch warehouse ID
99
  {
@@ -112,7 +132,6 @@ apis = [
112
  llm = ChatOpenAI(model="gpt-4o-mini", max_tokens=300, temperature=0.1)
113
  llm_chart = OpenAI()
114
 
115
-
116
  def get_schema(_):
117
  schema_info = db.get_table_info() # This should be a string of your SQL schema
118
  return schema_info
@@ -161,9 +180,12 @@ def database_tool(question):
161
 
162
  def get_ASN_data(question):
163
  base_url = os.getenv("ASN_API_URL")
 
164
  complete_url = f"{base_url}branchMaster.id=343&transactionUid={question}&userId=164&transactionType=ASN"
165
  try:
166
  response = requests.get(complete_url)
 
 
167
  data = response.json()
168
  response.raise_for_status()
169
 
@@ -246,6 +268,10 @@ def summarize_document(docs):
246
  texts = load_and_split_pdf(pdf_path)
247
  vector_store = create_vector_store(texts)
248
 
 
 
 
 
249
 
250
  def document_data_tool(question):
251
  print(f"Document data tool enter: {question}")
@@ -256,8 +282,6 @@ def document_data_tool(question):
256
 
257
  # mailjet API since SMTP is not supported HF spaces
258
  def send_email_with_attachment_mailjet(recipient_email, subject, body, attach_img_base64=None):
259
-
260
-
261
  api_key = os.getenv("MAILJET_API_KEY")
262
  api_secret = os.getenv("MAILJET_API_SECRET")
263
 
@@ -350,8 +374,6 @@ def send_email_with_attachment(recipient_email, subject, body, attachment_path):
350
  def make_api_request(url, params):
351
  """Generic function to make API GET requests and return JSON data."""
352
  try:
353
- print(url)
354
- print(params)
355
  response = requests.get(url, params=params)
356
  response.raise_for_status() # Raises an HTTPError if the response was an error
357
  return response.json() # Return the parsed JSON data
@@ -377,18 +399,14 @@ def inventory_report(question):
377
  if data:
378
  # Extracting the id for the warehouse with the name "WH"
379
  warehouse_id = next((item['id'] for item in data['result'] if item['wareHouseId'] == warehouse_name), None)
380
- #print(warehouse_id)
381
- if (warehouse_id):
382
-
383
- # print(f"The id for the warehouse named {name} is: {warehouse_id}")
384
  # Step 3: Update the placeholder with the actual warehouse_id
385
  for api in apis:
386
  if "warehouseId" in api["params"]:
387
  api["params"]["warehouseId"] = warehouse_id
388
-
389
- print(f"warehouseId: {warehouse_id}")
390
- print(f"warehouseId: {apis[1]}")
391
-
392
  data1 = make_api_request(apis[1]["url"], apis[1]["params"])
393
  if (data1):
394
  headers = ["S.No", "Warehouse Code", "Warehouse Name", "Customer Code", "Customer Name", "Item Code", "Item Name",
@@ -416,20 +434,25 @@ def inventory_report(question):
416
 
417
  # Convert to pandas DataFrame
418
  df = pd.DataFrame(table_data, columns=headers)
 
 
419
 
420
- sdf = SmartDataframe(df, config={"llm": llm_chart})
421
-
422
- # chart = sdf.chat("Can you draw a bar chart with all avaialble item name and quantity.")
423
- chart = sdf.chat(question)
424
-
425
- return chart
426
  else:
427
  return "There are no inventory details for the warehouse you have given."
428
  else:
429
  return "Please provide a warehouse name available in the database."
430
 
 
 
 
 
431
 
432
- # inventory_report("WH:can you give me a bar chart with item name and quantity for the warehouse WH")
 
 
 
 
433
 
434
  # Define input and output models using Pydantic
435
  class QueryInput(BaseModel):
@@ -446,6 +469,7 @@ class QueryOutput(BaseModel):
446
 
447
  # Wrap the function with StructuredTool for better parameter handling
448
  tools = [
 
449
  StructuredTool(
450
  func=get_ASN_data,
451
  name="APIData",
@@ -486,6 +510,7 @@ tools = [
486
  ]
487
 
488
  prompt_template = f"""You are an assistant that helps with database queries, API information, and document retrieval. Your job is to provide clear, complete, and detailed responses to the following queries. Please give the output response in an user friendly way and remove "**" from the response. For example, document related queries can be answered in a clear and concise way with numbering and not as a paragraph. Database related queries should be answered with proper indentation and use numbering for the rows. ASN id related queries should be answered with proper indentation and use numbering for the rows.
 
489
  For ASN id related questions, if the user specifies an ASN id, provide the information from the api tool. Pass only the id as input to the tool. Do not pass the entire question as input to the tool. If the details are not found, say it in a clear and concise way.
490
  You are an AI assistant trained to help with warehouse management questions based on a detailed document about our WMS. The document covers various processes such as ASN handling, purchase orders, cross docking, appointment scheduling for shipments, and yard management. Please provide a complete and concise response within 200 words and Ensure that the response is not truncated and covers the essential points. When answering, focus on providing actionable insights and clear explanations related to the specific query. Please remove "**" from the response.
491
  For SQL database-related questions, only use the fields available in the warehouse schema, including tables such as customer_master, efs_company_master, efs_group_company_master, efs_region_master, party_address_detail, wms_warehouse_master.
@@ -493,18 +518,13 @@ For datavisualization, user will ask for inventory report of a particular wareho
493
  {{agent_scratchpad}}
494
  Here is the information you need to process:
495
  Question: {{input}}"""
496
-
497
- llm = llm.bind()
498
- agent = create_tool_calling_agent(llm, tools, ChatPromptTemplate.from_template(prompt_template))
499
- agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
500
-
501
 
502
  def ensure_temp_chart_dir():
503
  temp_chart_dir = os.getenv("IMAGE_MAIN_URL")
504
  if not os.path.exists(temp_chart_dir):
505
  os.makedirs(temp_chart_dir)
506
 
507
-
508
  def clean_gradio_tmp_dir():
509
  tmp_dir = os.getenv("IMAGE_GRADIO_PATH")
510
  if os.path.exists(tmp_dir):
@@ -609,18 +629,8 @@ def answer_question_thread(user_question, chatbot, audio=None):
609
 
610
  while iterations < max_iterations:
611
 
612
- """if "send email to" in user_question:
613
- email_match = re.search(r"send email to ([\w\.-]+@[\w\.-]+)", user_question)
614
- if email_match:
615
- user_email = email_match.group(1).strip()
616
- user_question = user_question.replace(f"send email to {user_email}", "").strip()
617
- user_question = f"{user_question}:{user_email}"
618
- """
619
-
620
  response = agent_executor.invoke({"input": user_question}, config={"callbacks": [langfuse_handler]}, early_stopping_method="generate")
621
- print("response generated")
622
- print(response)
623
-
624
  if isinstance(response, dict):
625
  response_text = response.get("output", "")
626
  else:
@@ -711,14 +721,6 @@ def answer_question(user_question, chatbot, audio=None):
711
 
712
  while iterations < max_iterations:
713
 
714
- """if "send email to" in user_question:
715
- email_match = re.search(r"send email to ([\w\.-]+@[\w\.-]+)", user_question)
716
- if email_match:
717
- user_email = email_match.group(1).strip()
718
- user_question = user_question.replace(f"send email to {user_email}", "").strip()
719
- user_question = f"{user_question}:{user_email}"
720
- """
721
-
722
  response = agent_executor.invoke({"input": user_question}, config={"callbacks": [langfuse_handler]})
723
 
724
  if isinstance(response, dict):
@@ -731,6 +733,8 @@ def answer_question(user_question, chatbot, audio=None):
731
 
732
  if iterations == max_iterations:
733
  return "The agent could not generate a valid response within the iteration limit."
 
 
734
 
735
  if os.getenv("IMAGE_PATH") in response_text:
736
  # Open the image file
@@ -742,7 +746,7 @@ def answer_question(user_question, chatbot, audio=None):
742
  img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
743
 
744
  img = f'<img src="data:image/png;base64,{img_str}" style="width:450px; height:400px;">'
745
- # image = gr.Image(value=img_str)
746
  chatbot.append((user_question, img))
747
 
748
  email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
@@ -778,21 +782,45 @@ def answer_question(user_question, chatbot, audio=None):
778
  print(f"Error loading image file: {e}")
779
  chatbot.append((user_question, "Chart generation failed. Please try again."))
780
  return gr.update(value=chatbot)
781
-
782
-
783
- # return [(user_question,gr.Image("/home/user/app/exports/charts/temp_chart.png"))]
784
- # return "/home/user/app/exports/charts/temp_chart.png"
785
  else:
786
  chatbot.append((user_question, response_text))
787
  return gr.update(value=chatbot)
788
- # response_text = response_text.replace('\n', ' ').replace(' ', ' ').strip()
789
- # return response_text
790
-
791
- def submit_feedback(feedback, chatbot):
792
  gr.Info("Thank you for your feedback.")
 
 
793
  feedback_response = "User feedback: " + feedback
794
  return chatbot + [(feedback_response, None)], gr.update(visible=False), gr.update(visible=False)
795
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
  def handle_dislike(data: gr.LikeData):
797
  if not data.liked:
798
  print("downvote")
@@ -806,14 +834,296 @@ def handle_dislike(data: gr.LikeData):
806
  def update_message(request: gr.Request):
807
  return f"<h2 style=' font-family: Calibri;'>Welcome, {request.username}</h4>"
808
 
809
- def send_mail_with_history(req: gr.Request,chatbot):
810
- if req.username:
811
- send_email_with_attachment_mailjet("lakshmivairamani@gmail.com","conversation history" + req.username, chatbot)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
812
 
 
 
813
  def upload_file(filepath):
814
- gr.Info("File uploaded")
815
- # CSS for styling the buttons and other elements
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
816
  css = """
 
817
  /* Example of custom button styling */
818
  .gr-button {
819
  background-color: #6366f1; /* Change to your desired button color */
@@ -823,7 +1133,6 @@ css = """
823
  padding: 10px 20px;
824
  font-size: 12px;
825
  cursor: pointer;
826
-
827
  }
828
 
829
  .gr-button:hover {
@@ -838,14 +1147,12 @@ css = """
838
  padding: 10px 20px;
839
  font-size: 14px;
840
  cursor: pointer;
841
-
842
  }
843
 
844
  .gr-buttonbig:hover {
845
  background-color: #8a92f7; /* Darker shade on hover */
846
  }
847
 
848
-
849
  /* Customizing the Logout link to be on the right */
850
  .logout-link {
851
  text-align: right;
@@ -858,59 +1165,106 @@ css = """
858
  text-decoration: none;
859
  font-size: 16px;
860
  }
 
861
  .chatbot_gpt {
862
- /* width: 800px !important; Adjust width as needed */
863
  height: 600px !important; /* Adjust height as needed */
864
  }
 
865
  .logout-link a:hover {
866
  text-decoration: underline; /* Underline on hover */
867
  }
 
868
  .message-buttons-right{
869
  display: none !important;
870
  }
 
871
  body, .gradio-container {
872
  margin: 0;
873
  padding: 0;
874
  }
875
- """
876
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877
  with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
878
  gr.HTML("<CENTER><B><h1 style='font-size:30px; font-family: Calibri;'>RedMindGPT</h1></B></CENTER>")
 
 
 
 
879
  with gr.Row():
880
  m = gr.Markdown()
881
  demo.load(update_message, None, m)
882
-
883
- # Logout link styled as text link in the right corner
884
- gr.Markdown("<div class='logout-link'><a href='/logout'><b>Logout</b></a></div>")
885
-
886
  with gr.Row():
887
- sample_button = gr.Button("What are the details of ASN24091600002",elem_classes="gr-buttonbig")
888
- sample_button1 = gr.Button("What are the active warehouses available",elem_classes="gr-buttonbig")
889
- sample_button2 = gr.Button("Explain Pre-Receiving Yard Management",elem_classes="gr-buttonbig")
890
- sample_button3 = gr.Button("Can you generate a pie chart with item names and quantities in warehouse WH1000001",elem_classes="gr-buttonbig")
891
  sample_button4 = gr.Button("Analyze item name & quantity for different customers in a stacked bar chart for the warehouse WH1000001 & send email to meetarun@gmail.com", elem_classes="gr-button")
892
 
 
893
  with gr.Row():
894
- chatbot = gr.Chatbot(label="Select any of the questions listed above to experience RedmindGPT in action.",elem_classes="chatbot_gpt")
895
 
 
896
  with gr.Row():
897
  with gr.Column(scale=1):
898
  message = gr.Textbox(show_label=False, container=False, placeholder="Please enter your question")
899
-
900
  with gr.Row():
901
  feedback_textbox = gr.Textbox(visible=False, show_label=False, container=False, placeholder="Please enter your feedback.")
902
- submit_feedback_button = gr.Button("Submit Feedback", visible=False,elem_classes="gr-buttonbig")
903
  with gr.Column(scale=1):
904
  with gr.Row():
905
- button = gr.Button("Submit", elem_id="submit",elem_classes="gr-buttonbig")
906
- # Button to stop the current processing
907
  stop_button = gr.Button("Stop", elem_classes="gr-buttonbig")
908
- u = gr.UploadButton("Upload a file", file_count="single")
909
- u.upload(upload_file, u)
910
- #gr.ClearButton(message, elem_classes="gr-buttonbig")
911
-
912
- stop_button.click(stop_processing, [chatbot],[chatbot])
 
 
 
 
 
 
 
 
 
913
 
 
 
 
 
 
 
 
914
  button.click(handle_query, [message, chatbot], [chatbot])
915
  message.submit(handle_query, [message, chatbot], [chatbot])
916
  message.submit(lambda x: gr.update(value=""), None, [message], queue=False)
@@ -920,14 +1274,15 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
920
  submit_feedback_button.click(submit_feedback, [feedback_textbox, chatbot], [chatbot, feedback_textbox, submit_feedback_button])
921
  submit_feedback_button.click(lambda x: gr.update(value=''), [], [feedback_textbox])
922
 
923
- #sample_button.click(answer_question, [sample_button, chatbot], [chatbot])
924
  sample_button.click(handle_query, [sample_button, chatbot], [chatbot])
925
  sample_button1.click(handle_query, [sample_button1, chatbot], [chatbot])
926
  sample_button2.click(handle_query, [sample_button2, chatbot], [chatbot])
927
  sample_button3.click(handle_query, [sample_button3, chatbot], [chatbot])
928
  sample_button4.click(handle_query, [sample_button4, chatbot], [chatbot])
929
 
930
- #demo.unload(lambda: send_mail_with_history(chatbot))
931
- demo.title = "RedmindGPT"
932
- #user_details for login page
933
- demo.launch(auth=[("lakshmi", "redmind"), ("arun", "redmind"), ("NewageGlobal", "Newage123$")], auth_message= " RedmindGPT",inline=False)
 
 
 
11
  import shutil
12
  import json
13
  import nltk
14
+ import mysql.connector
15
+ import fnmatch
16
+ # audio related code is not included based on Arun's input
17
  # audio package
18
+ import speech_recognition as sr
19
  from pydub import AudioSegment
20
+ from pydub.playback import play
21
+ # SMTP code is not included since HFSpaces doesn't support it
22
  # email library
23
+ import smtplib, ssl
24
  from email.mime.multipart import MIMEMultipart
25
  from email.mime.text import MIMEText
26
  from email.mime.base import MIMEBase
27
+ from email import encoders
28
  # langchain
29
  from langchain_core.prompts import ChatPromptTemplate
30
  from langchain_core.output_parsers import StrOutputParser
 
36
  from langchain.agents import create_tool_calling_agent, AgentExecutor, Tool
37
  from langchain.text_splitter import RecursiveCharacterTextSplitter
38
  from langchain.tools import StructuredTool
39
+ #from langchain.pydantic_v1 import BaseModel, Field
40
+ from pydantic import BaseModel, Field
41
  from PyPDF2 import PdfReader
42
  from nltk.tokenize import sent_tokenize
43
  from datetime import datetime
44
  from sqlalchemy import create_engine
45
  from sqlalchemy.sql import text
46
+ import openai
47
 
48
  # pandas
49
  import pandas as pd
 
68
  from mailjet_rest import Client
69
  import base64
70
 
71
+ #Variables Initialization
72
+ agent_executor = None
73
+ vector_store1 = None
74
+ texts1 = None
75
+ excel_dataframe = None
76
+ file_extension = None
77
+ #This is to define the summary of the runtime tool. This summary will be updated in prompt template and description of the new tool
78
+ run_time_tool_summary=""
79
+
80
  # Define global variables for managing the thread and current_event
81
  executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
82
  current_event = None
 
87
  os.environ["LANGFUSE_SECRET_KEY"] = os.getenv("LANGFUSE_SECRET_KEY")
88
  os.environ["LANGFUSE_HOST"] = os.getenv("LANGFUSE_HOST")
89
 
90
+ DB_USER = 'u852023448_redmindgpt'
91
+ DB_PASSWORD = 'redmindGpt@123'
92
+ DB_HOST = '217.21.88.10'
93
+ DB_NAME = 'u852023448_redmindgpt'
94
+
95
+
96
  langfuse_handler = CallbackHandler()
97
  langfuse_handler.auth_check() # Optional: Checks if the authentication is successful
98
 
99
  nltk.download('punkt')
100
 
101
+ open_api_key_token = os.getenv("OPENAI_API_KEY")
102
 
103
  os.environ['OPENAI_API_KEY'] = open_api_key_token
104
  pdf_path = "Inbound.pdf"
105
 
106
  db_uri = os.getenv("POSTGRESQL_CONNECTION")
 
107
 
108
+ # Database setup
109
  db = SQLDatabase.from_uri(db_uri)
110
 
111
  user_email = ""
 
113
  warehouse_id = ""
114
  # Today's date to be populated in inventory API
115
  inventory_date = datetime.today().strftime('%Y-%m-%d')
116
+
117
  apis = [
118
  # fetch warehouse ID
119
  {
 
132
  llm = ChatOpenAI(model="gpt-4o-mini", max_tokens=300, temperature=0.1)
133
  llm_chart = OpenAI()
134
 
 
135
  def get_schema(_):
136
  schema_info = db.get_table_info() # This should be a string of your SQL schema
137
  return schema_info
 
180
 
181
  def get_ASN_data(question):
182
  base_url = os.getenv("ASN_API_URL")
183
+ print(f"base_url{base_url}")
184
  complete_url = f"{base_url}branchMaster.id=343&transactionUid={question}&userId=164&transactionType=ASN"
185
  try:
186
  response = requests.get(complete_url)
187
+ print(f"complete_url{complete_url}")
188
+ print(f"response{response}")
189
  data = response.json()
190
  response.raise_for_status()
191
 
 
268
  texts = load_and_split_pdf(pdf_path)
269
  vector_store = create_vector_store(texts)
270
 
271
+ def document_data_tool_runtime(question):
272
+ print(f"Document data runtime tool enter: {question} with {vector_store1}")
273
+ query_response = query_vector_store(vector_store1, question, config={"callbacks": [langfuse_handler]})
274
+ return query_response
275
 
276
  def document_data_tool(question):
277
  print(f"Document data tool enter: {question}")
 
282
 
283
  # mailjet API since SMTP is not supported HF spaces
284
  def send_email_with_attachment_mailjet(recipient_email, subject, body, attach_img_base64=None):
 
 
285
  api_key = os.getenv("MAILJET_API_KEY")
286
  api_secret = os.getenv("MAILJET_API_SECRET")
287
 
 
374
  def make_api_request(url, params):
375
  """Generic function to make API GET requests and return JSON data."""
376
  try:
 
 
377
  response = requests.get(url, params=params)
378
  response.raise_for_status() # Raises an HTTPError if the response was an error
379
  return response.json() # Return the parsed JSON data
 
399
  if data:
400
  # Extracting the id for the warehouse with the name "WH"
401
  warehouse_id = next((item['id'] for item in data['result'] if item['wareHouseId'] == warehouse_name), None)
402
+
403
+ if (warehouse_id):
404
+
 
405
  # Step 3: Update the placeholder with the actual warehouse_id
406
  for api in apis:
407
  if "warehouseId" in api["params"]:
408
  api["params"]["warehouseId"] = warehouse_id
409
+
 
 
 
410
  data1 = make_api_request(apis[1]["url"], apis[1]["params"])
411
  if (data1):
412
  headers = ["S.No", "Warehouse Code", "Warehouse Name", "Customer Code", "Customer Name", "Item Code", "Item Name",
 
434
 
435
  # Convert to pandas DataFrame
436
  df = pd.DataFrame(table_data, columns=headers)
437
+
438
+ chart_link = chat_with_llm(df,question)
439
 
440
+ return chart_link
 
 
 
 
 
441
  else:
442
  return "There are no inventory details for the warehouse you have given."
443
  else:
444
  return "Please provide a warehouse name available in the database."
445
 
446
+ def chat_with_llm(df,question):
447
+ sdf = SmartDataframe(df, config={"llm": llm_chart})
448
+ llm_response = sdf.chat(question)
449
+ return llm_response
450
 
451
+ def bind_llm(llm, tools,prompt_template):
452
+ llm = llm.bind()
453
+ agent = create_tool_calling_agent(llm, tools, ChatPromptTemplate.from_template(prompt_template))
454
+ agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
455
+ return agent_executor
456
 
457
  # Define input and output models using Pydantic
458
  class QueryInput(BaseModel):
 
469
 
470
  # Wrap the function with StructuredTool for better parameter handling
471
  tools = [
472
+
473
  StructuredTool(
474
  func=get_ASN_data,
475
  name="APIData",
 
510
  ]
511
 
512
  prompt_template = f"""You are an assistant that helps with database queries, API information, and document retrieval. Your job is to provide clear, complete, and detailed responses to the following queries. Please give the output response in an user friendly way and remove "**" from the response. For example, document related queries can be answered in a clear and concise way with numbering and not as a paragraph. Database related queries should be answered with proper indentation and use numbering for the rows. ASN id related queries should be answered with proper indentation and use numbering for the rows.
513
+
514
  For ASN id related questions, if the user specifies an ASN id, provide the information from the api tool. Pass only the id as input to the tool. Do not pass the entire question as input to the tool. If the details are not found, say it in a clear and concise way.
515
  You are an AI assistant trained to help with warehouse management questions based on a detailed document about our WMS. The document covers various processes such as ASN handling, purchase orders, cross docking, appointment scheduling for shipments, and yard management. Please provide a complete and concise response within 200 words and Ensure that the response is not truncated and covers the essential points. When answering, focus on providing actionable insights and clear explanations related to the specific query. Please remove "**" from the response.
516
  For SQL database-related questions, only use the fields available in the warehouse schema, including tables such as customer_master, efs_company_master, efs_group_company_master, efs_region_master, party_address_detail, wms_warehouse_master.
 
518
  {{agent_scratchpad}}
519
  Here is the information you need to process:
520
  Question: {{input}}"""
521
+ agent_executor = bind_llm(llm,tools,prompt_template)
 
 
 
 
522
 
523
  def ensure_temp_chart_dir():
524
  temp_chart_dir = os.getenv("IMAGE_MAIN_URL")
525
  if not os.path.exists(temp_chart_dir):
526
  os.makedirs(temp_chart_dir)
527
 
 
528
  def clean_gradio_tmp_dir():
529
  tmp_dir = os.getenv("IMAGE_GRADIO_PATH")
530
  if os.path.exists(tmp_dir):
 
629
 
630
  while iterations < max_iterations:
631
 
 
 
 
 
 
 
 
 
632
  response = agent_executor.invoke({"input": user_question}, config={"callbacks": [langfuse_handler]}, early_stopping_method="generate")
633
+
 
 
634
  if isinstance(response, dict):
635
  response_text = response.get("output", "")
636
  else:
 
721
 
722
  while iterations < max_iterations:
723
 
 
 
 
 
 
 
 
 
724
  response = agent_executor.invoke({"input": user_question}, config={"callbacks": [langfuse_handler]})
725
 
726
  if isinstance(response, dict):
 
733
 
734
  if iterations == max_iterations:
735
  return "The agent could not generate a valid response within the iteration limit."
736
+
737
+
738
 
739
  if os.getenv("IMAGE_PATH") in response_text:
740
  # Open the image file
 
746
  img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
747
 
748
  img = f'<img src="data:image/png;base64,{img_str}" style="width:450px; height:400px;">'
749
+
750
  chatbot.append((user_question, img))
751
 
752
  email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
 
782
  print(f"Error loading image file: {e}")
783
  chatbot.append((user_question, "Chart generation failed. Please try again."))
784
  return gr.update(value=chatbot)
785
+
 
 
 
786
  else:
787
  chatbot.append((user_question, response_text))
788
  return gr.update(value=chatbot)
789
+
790
+
791
+ def submit_feedback(feedback, chatbot, request: gr.Request):
 
792
  gr.Info("Thank you for your feedback.")
793
+ #save feedback with user question and response in database
794
+ save_feedback(request.username,chatbot[-1][0], chatbot[-1][1], feedback)
795
  feedback_response = "User feedback: " + feedback
796
  return chatbot + [(feedback_response, None)], gr.update(visible=False), gr.update(visible=False)
797
 
798
+
799
+ # Function to connect to MySQL database
800
+ def connect_to_db():
801
+ return mysql.connector.connect(
802
+ host=DB_HOST,
803
+ user=DB_USER,
804
+ password=DB_PASSWORD,
805
+ database=DB_NAME
806
+ )
807
+
808
+ # Function to save feedback to the database
809
+ def save_feedback(username, user_question, user_response, feedback):
810
+ try:
811
+ conn = connect_to_db()
812
+ cursor = conn.cursor()
813
+ query = "INSERT INTO user_feedback (username, question, response, feedback) VALUES (%s, %s, %s, %s)"
814
+ cursor.execute(query, (username, user_question, user_response, feedback))
815
+ conn.commit()
816
+ except mysql.connector.Error as err:
817
+ print(f"Error: {err}")
818
+ finally:
819
+ if cursor:
820
+ cursor.close()
821
+ if conn:
822
+ conn.close()
823
+
824
  def handle_dislike(data: gr.LikeData):
825
  if not data.liked:
826
  print("downvote")
 
834
  def update_message(request: gr.Request):
835
  return f"<h2 style=' font-family: Calibri;'>Welcome, {request.username}</h4>"
836
 
837
+ # Function to generate a 50-word summary of the newly uploaded doc using OpenAI
838
+ def generate_summary(text):
839
+ prompt = (
840
+ "You are an AI that helps with document analysis. Please provide a concise title and a summary of the following document. "
841
+ "The summary should be about 50 words and include key details that can help answer questions accurately:\n\n"
842
+ f"{text}\n\nTitle : Summary"
843
+ )
844
+ # Call the OpenAI API to generate a summary
845
+ response = openai.chat.completions.create(
846
+ messages=[
847
+ {
848
+ "role": "user",
849
+ "content": prompt,
850
+ }
851
+ ],
852
+ model="gpt-4o-mini",
853
+ )
854
+ # Extract the title and summary from the response
855
+ response_content = response.choices[0].message.content
856
+ lines = response_content.split("\n")
857
+ # Extract title
858
+ title_line = lines[0]
859
+ title = title_line.split("**Title:**")[-1].strip()
860
+
861
+ # Extract summary
862
+ summary_line = lines[2]
863
+ summary = summary_line.split("**Summary:**")[-1].strip()
864
 
865
+ return title, summary
866
+ #function to handle file upload decide whether excel or doc is uploaded and respective tool will be created with appropriate prompts at runtime
867
  def upload_file(filepath):
868
+ global vector_store1, file_extension
869
+
870
+ # Get the file extension
871
+ _, file_extension = os.path.splitext(filepath)
872
+
873
+ if file_extension == ".pdf":
874
+ texts1 = load_and_split_pdf(filepath)
875
+
876
+ vector_store1 = create_vector_store(texts1)
877
+ # Generate a 50-word summary from the extracted text
878
+ title, summary = generate_summary(texts1)
879
+ return title, summary, file_extension
880
+ elif file_extension == ".xlsx":
881
+ title, prompt = process_excel(filepath)
882
+ return title, prompt
883
+
884
+ def generate_example_questions(sheet_name, column_headers):
885
+ """
886
+ Generates natural language questions based on column headers.
887
+
888
+ Args:
889
+ sheet_name (str): The name of the Excel sheet.
890
+ column_headers (list): List of column headers from the sheet.
891
+
892
+ Returns:
893
+ questions (list): List of generated questions based on the columns.
894
+ """
895
+ questions = []
896
+
897
+ # Check for typical columns and create questions
898
+ if 'Product Name' in column_headers or 'Product' in column_headers:
899
+ questions.append(f"What is the total sales for a specific product in {sheet_name}?")
900
+
901
+ if 'Sales Amount' in column_headers or 'Amount' in column_headers:
902
+ questions.append(f"What is the total sales amount for a specific region in {sheet_name}?")
903
+
904
+ if 'Region' in column_headers:
905
+ questions.append(f"Which region had the highest sales in {sheet_name}?")
906
+
907
+ if 'Date' in column_headers:
908
+ questions.append(f"What were the total sales during a specific month in {sheet_name}?")
909
+
910
+ if 'Price' in column_headers:
911
+ questions.append(f"What is the price of a specific product in {sheet_name}?")
912
+
913
+ if any(fnmatch.fnmatch(header, 'Employee*') for header in column_headers):
914
+ questions.append(f"What are the details of the employee names with distinct broker names?")
915
+
916
+ return questions
917
+
918
+ def generate_prompt_from_excel_file(df_dict):
919
+ """
920
+ Generates a prompt from an Excel file containing multiple sheets.
921
+
922
+ Args:
923
+ excel_file_path (str): The path to the Excel file.
924
+
925
+ Returns:
926
+ prompt (str): A detailed prompt including sheet names, column headers, sample data,
927
+ and example questions for each sheet.
928
+ """
929
+
930
+ # Initialize prompt with basic structure
931
+ prompt = "You have been provided with an Excel file containing data in several sheets.\n"
932
+
933
+ # Loop through each sheet to extract column headers and sample data
934
+ for sheet_name, sheet_df in df_dict.items():
935
+ # Extract column headers
936
+ column_headers = list(sheet_df.columns)
937
+
938
+ # Get a sample of the data (first few rows)
939
+ sample_data = sheet_df.head(3).to_string(index=False)
940
+
941
+ # Add sheet details to the prompt
942
+ prompt += f"For the sheet '{sheet_name}', the column headers are:"
943
+ prompt += f"{', '.join(column_headers)}\n\n"
944
+ #prompt += f"Example data from sheet '{sheet_name}':\n"
945
+ #prompt += f"{sample_data}\n\n"
946
+
947
+ # Generate example natural language questions based on columns
948
+ example_questions = generate_example_questions(sheet_name, column_headers)
949
+ #prompt += "### Example Questions:\n"
950
+ #for question in example_questions:
951
+ # prompt += f"- {question}\n"
952
+ #prompt += "\n"
953
+
954
+ # Finalize the prompt with function call description
955
+
956
+ prompt += f"- Query: A natural language question (e.g., {example_questions}).\n"
957
+ prompt += "The function should return a result based on the Excel data, such as specific values, calculations, or summaries.\n"
958
+
959
+ return "Excel data", prompt
960
+
961
+ # Function to handle "Add to RedMindGPT" button click
962
+ def add_to_redmindgpt(title, summary):
963
+ """
964
+ Adds a document or Excel file to the RedmindGPT system and configures the appropriate runtime tool for handling related queries.
965
+ Parameters:
966
+ title (str): The title of the document or Excel file.
967
+ summary (str): A brief summary of the document or Excel file.
968
+ Returns:
969
+ str: A message indicating whether the file has been added successfully.
970
+ Behavior:
971
+ - If the file extension is ".pdf", it sets up a runtime tool for handling document-related queries.
972
+ - If the file extension is ".xlsx", it sets up a runtime tool for handling Excel data-related queries.
973
+ - Configures the prompt template for the agent executor based on the file type.
974
+ - Adds the configured runtime tool to the list of tools used by the agent executor.
975
+ """
976
+
977
+ global agent_executor, file_extension
978
+
979
+ if file_extension == ".pdf":
980
+ run_time_tool_summary = f"For {title} document related questions, Please refer runtimeDocumentData tool. {summary}. Please provide a complete and concise response within 200 words and Ensure that the response is not truncated and covers the essential points."
981
+
982
+ run_time_tool = StructuredTool(
983
+ func=document_data_tool_runtime,
984
+ name="runtimeDocumentData",
985
+ args_schema=QueryInput,
986
+ output_schema=QueryOutput,
987
+ description=f"You are an AI assistant trained to help with the questions based on the uploaded document {title}. {summary}. Please provide a complete and concise response within 200 words and Ensure that the response is not truncated and covers the essential points."
988
+ )
989
+
990
+ # Add the new tool to the beginning
991
+ tools.insert(0, run_time_tool)
992
+
993
+ prompt_template = f"""You are an assistant that helps with database queries, API information, and document retrieval. Your job is to provide clear, complete, and detailed responses to the following queries. Please give the output response in an user friendly way and remove "**" from the response. For example, document related queries can be answered in a clear and concise way with numbering and not as a paragraph. Database related queries should be answered with proper indentation and use numbering for the rows. ASN id related queries should be answered with proper indentation and use numbering for the rows.
994
+ {run_time_tool_summary}
995
+ For ASN id related questions, if the user specifies an ASN id, provide the information from the api tool. Pass only the id as input to the tool. Do not pass the entire question as input to the tool. If the details are not found, say it in a clear and concise way.
996
+ You are an AI assistant trained to help with warehouse management questions based on a detailed document about our WMS. The document covers various processes such as ASN handling, purchase orders, cross docking, appointment scheduling for shipments, and yard management. Please provide a complete and concise response within 200 words and Ensure that the response is not truncated and covers the essential points. When answering, focus on providing actionable insights and clear explanations related to the specific query. Please remove "**" from the response.
997
+ For SQL database-related questions, only use the fields available in the warehouse schema, including tables such as customer_master, efs_company_master, efs_group_company_master, efs_region_master, party_address_detail, wms_warehouse_master.
998
+ For datavisualization, user will ask for inventory report of a particular warehouse. Your job is to return the image path to chat interface and display the image as output.
999
+
1000
+ {{agent_scratchpad}}
1001
+ Here is the information you need to process:
1002
+ Question: {{input}}"""
1003
+ agent_executor = bind_llm(llm,tools,prompt_template)
1004
+ return f"File has been added successfully."
1005
+ elif file_extension == ".xlsx":
1006
+ run_time_excel_tool_summary = f"For {title} related questions, Please refer runtimeExcelData tool. {summary}. "
1007
+
1008
+ run_time_excel_tool = StructuredTool(
1009
+ func=chat_with_excel_data_dataframe,
1010
+ name="runtimeExcelData",
1011
+ args_schema=QueryInput,
1012
+ output_schema=QueryOutput,
1013
+ description="""You are an AI assistant trained to handle Excel data and return meaningful insights. Please display the output as below. If the output is not in the below format, please display the error message returned by the function as response.
1014
+ There are a total of {total_rows} rows. Please download the complete dataset here: <a href="https://redmindtechnologies.com/alborj/test.xlsx" download>Download</a>. Here are the first 3 rows:
1015
+ {sample_table}"""
1016
+ )
1017
+
1018
+ # Add the new tool to the beginning
1019
+ tools.insert(0, run_time_excel_tool)
1020
+
1021
+ prompt_template = f"""You are an assistant that helps with database queries, API information, and document retrieval. Your job is to provide clear, complete, and detailed responses to the following queries. Please give the output response in an user friendly way and remove "**" from the response. For example, document related queries can be answered in a clear and concise way with numbering and not as a paragraph. Database related queries should be answered with proper indentation and use numbering for the rows. ASN id related queries should be answered with proper indentation and use numbering for the rows.
1022
+ {run_time_excel_tool_summary}
1023
+ For ASN id related questions, if the user specifies an ASN id, provide the information from the api tool. Pass only the id as input to the tool. Do not pass the entire question as input to the tool. If the details are not found, say it in a clear and concise way.
1024
+ You are an AI assistant trained to help with warehouse management questions based on a detailed document about our WMS. The document covers various processes such as ASN handling, purchase orders, cross docking, appointment scheduling for shipments, and yard management. Please provide a complete and concise response within 200 words and Ensure that the response is not truncated and covers the essential points. When answering, focus on providing actionable insights and clear explanations related to the specific query. Please remove "**" from the response.
1025
+ For SQL database-related questions, only use the fields available in the warehouse schema, including tables such as customer_master, efs_company_master, efs_group_company_master, efs_region_master, party_address_detail, wms_warehouse_master.
1026
+ For datavisualization, user will ask for inventory report of a particular warehouse. Your job is to return the image path to chat interface and display the image as output.
1027
+
1028
+ {{agent_scratchpad}}
1029
+ Here is the information you need to process:
1030
+ Question: {{input}}"""
1031
+ agent_executor = bind_llm(llm,tools,prompt_template)
1032
+ return f"File has been added successfully."
1033
+
1034
+ def process_excel(file):
1035
+ global excel_dataframe
1036
+ # Check if the file is None
1037
+ if file is None:
1038
+ return "Excel file", "Your excel does not have values. Please upload a different file." # Return an empty dataframe if no file is uploaded
1039
+ else:
1040
+ # Read the uploaded Excel file
1041
+ excel_dataframe = pd.read_excel(file.name, sheet_name=None) # 'file.name' to get the actual file path
1042
+
1043
+ #to get title and summary of excel file
1044
+ title, prompt = generate_prompt_from_excel_file(excel_dataframe)
1045
+ excel_dataframe = pd.read_excel(file.name)
1046
+
1047
+ return title, prompt # Return the success message.
1048
+
1049
+ def chat_with_excel_data(question):
1050
+ global excel_dataframe
1051
+ response_dataframe = chat_with_llm(excel_dataframe,question)
1052
+ return response_dataframe
1053
+
1054
+ def chat_with_excel_data_dataframe(question):
1055
+ response_dataframe = chat_with_excel_data(question)
1056
+ #handle large dataset
1057
+ response = handle_large_dataset(response_dataframe)
1058
+ return response
1059
+
1060
+ #Save the respnse dataframe to an Excel file in hostinger so that the user can download it
1061
+ #save_file_path = "dataframe_output.xlsx"
1062
+ #response_dataframe.to_excel(save_file_path, index=False)
1063
+ #save_file_to_hostinger(save_file_path)
1064
+
1065
+ # Check if the response is a DataFrame
1066
+ """if isinstance(response_dataframe, pd.DataFrame):
1067
+ # Convert DataFrame to HTML for display
1068
+ df_html = response_dataframe.to_html(classes='dataframe', index=False)
1069
+ print(f"dfhtml:{df_html}")
1070
+ return df_html"""
1071
+
1072
+ #return response_dataframe.head(10)#, len(response_dataframe)
1073
+
1074
+ def save_file_to_hostinger(save_file_path):
1075
+ from ftplib import FTP
1076
+ # Step 2: FTP server credentials
1077
+ ftp_host = 'ftp.redmindtechnologies.com' # Replace with your FTP server address
1078
+ ftp_user = 'u852023448.redmindGpt' # Replace with your FTP username
1079
+ ftp_pass = 'RedMind@505' # Replace with your FTP password
1080
+ remote_file_path = '/alborj/test.xlsx' # Replace with the desired path on the server
1081
+
1082
+ # Create an FTP connection
1083
+ ftp = FTP(ftp_host)
1084
+ ftp.login(ftp_user, ftp_pass)
1085
+
1086
+ # Open the local file and upload it to the server
1087
+ with open(save_file_path, 'rb') as file:
1088
+ ftp.storbinary(f'STOR {remote_file_path}', file)
1089
+
1090
+ print(f'File {save_file_path} uploaded to {remote_file_path} on server.')
1091
+
1092
+ # Close the FTP connection
1093
+ ftp.quit()
1094
+
1095
+ def handle_large_dataset(df):
1096
+ total_rows = len(df)
1097
+ if total_rows < 4000:
1098
+
1099
+ # 1. Limit to first 10 rows
1100
+ limited_data = df.head(3)
1101
+
1102
+ # 2. Handle missing values
1103
+ limited_data.fillna("N/A", inplace=True)
1104
+ # 3. Drop the original first column
1105
+ limited_data_without_first_column = limited_data.iloc[:, 1:] # Skipping the original first column
1106
+
1107
+ # 4. Add SNo (serial number) as the first column, starting from 1
1108
+ limited_data_without_first_column.insert(0, 'SNo', range(1, len(limited_data_without_first_column) + 1))
1109
+ # 3. Save the full dataset to a downloadable file
1110
+ df.to_excel('output_data.xlsx', index=False)
1111
+ save_file_to_hostinger('output_data.xlsx')
1112
+ # 4. Create a summary and table of the first 10 rows for display
1113
+
1114
+ columns = list(df.columns)
1115
+ sample_table = limited_data_without_first_column.to_markdown()
1116
+
1117
+ # 5. Return the summary and downloadable link
1118
+ return f"""
1119
+ There are a total of {total_rows} rows. Please download the complete dataset here: <a href="https://redmindtechnologies.com/alborj/test.xlsx" download>Download</a>. Here are the first 3 rows:
1120
+ {sample_table} """
1121
+ else:
1122
+ return "Your query returns a large dataset which is not supported in the current version. Please try a different query."
1123
+
1124
+
1125
  css = """
1126
+
1127
  /* Example of custom button styling */
1128
  .gr-button {
1129
  background-color: #6366f1; /* Change to your desired button color */
 
1133
  padding: 10px 20px;
1134
  font-size: 12px;
1135
  cursor: pointer;
 
1136
  }
1137
 
1138
  .gr-button:hover {
 
1147
  padding: 10px 20px;
1148
  font-size: 14px;
1149
  cursor: pointer;
 
1150
  }
1151
 
1152
  .gr-buttonbig:hover {
1153
  background-color: #8a92f7; /* Darker shade on hover */
1154
  }
1155
 
 
1156
  /* Customizing the Logout link to be on the right */
1157
  .logout-link {
1158
  text-align: right;
 
1165
  text-decoration: none;
1166
  font-size: 16px;
1167
  }
1168
+
1169
  .chatbot_gpt {
 
1170
  height: 600px !important; /* Adjust height as needed */
1171
  }
1172
+
1173
  .logout-link a:hover {
1174
  text-decoration: underline; /* Underline on hover */
1175
  }
1176
+
1177
  .message-buttons-right{
1178
  display: none !important;
1179
  }
1180
+
1181
  body, .gradio-container {
1182
  margin: 0;
1183
  padding: 0;
1184
  }
 
1185
 
1186
+ /* Styling the tab header with a blue background */
1187
+ .gr-tab-header {
1188
+ background-color: #4A90E2; /* Blue background for the tab header */
1189
+ padding: 10px;
1190
+ border-radius: 8px;
1191
+ color: white;
1192
+ font-size: 16px;
1193
+ }
1194
+
1195
+ /* Styling the selected tab text color to be green */
1196
+ .gr-tab-header .gr-tab-active {
1197
+ color: green; /* Change selected tab text to green */
1198
+ }
1199
+
1200
+ /* Keep non-selected tab text color white */
1201
+ .gr-tab-header .gr-tab {
1202
+ color: white;
1203
+ }
1204
+
1205
+ /* Custom CSS for reducing the size of the video element */
1206
+ .video-player {
1207
+ width: 500px; /* Set a custom width for the video */
1208
+ height: 350px; /* Set a custom height for the video */
1209
+ margin: 0 auto; /* Center the video horizontally */
1210
+ }
1211
+ """
1212
  with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
1213
  gr.HTML("<CENTER><B><h1 style='font-size:30px; font-family: Calibri;'>RedMindGPT</h1></B></CENTER>")
1214
+ # Logout link styled as text link in the right corner
1215
+ gr.Markdown("<div class='logout-link'><a href='/logout'><b>Logout</b></a></div>")
1216
+
1217
+ # Unified RedMindGPT Interface
1218
  with gr.Row():
1219
  m = gr.Markdown()
1220
  demo.load(update_message, None, m)
1221
+
1222
+ # Buttons for sample queries
 
 
1223
  with gr.Row():
1224
+ sample_button = gr.Button("What are the details of ASN24091600002", elem_classes="gr-buttonbig")
1225
+ sample_button1 = gr.Button("What are the active warehouses available", elem_classes="gr-buttonbig")
1226
+ sample_button2 = gr.Button("Explain Pre-Receiving Yard Management", elem_classes="gr-buttonbig")
1227
+ sample_button3 = gr.Button("Can you generate a pie chart with item names and quantities in warehouse WH1000001", elem_classes="gr-buttonbig")
1228
  sample_button4 = gr.Button("Analyze item name & quantity for different customers in a stacked bar chart for the warehouse WH1000001 & send email to meetarun@gmail.com", elem_classes="gr-button")
1229
 
1230
+ # Chatbot component
1231
  with gr.Row():
1232
+ chatbot = gr.Chatbot(label="Select any of the questions listed above to experience RedMindGPT in action.", elem_classes="chatbot_gpt")
1233
 
1234
+ # Textbox for user questions
1235
  with gr.Row():
1236
  with gr.Column(scale=1):
1237
  message = gr.Textbox(show_label=False, container=False, placeholder="Please enter your question")
1238
+
1239
  with gr.Row():
1240
  feedback_textbox = gr.Textbox(visible=False, show_label=False, container=False, placeholder="Please enter your feedback.")
1241
+ submit_feedback_button = gr.Button("Submit Feedback", visible=False, elem_classes="gr-buttonbig")
1242
  with gr.Column(scale=1):
1243
  with gr.Row():
1244
+ button = gr.Button("Submit", elem_id="submit", elem_classes="gr-buttonbig")
 
1245
  stop_button = gr.Button("Stop", elem_classes="gr-buttonbig")
1246
+ # Rearranged to place Upload Doc and Upload Excel in the same row
1247
+ with gr.Row():
1248
+ with gr.Column(scale=1):
1249
+ # File Upload Section
1250
+ gr.Markdown("**Add a document or Excel for natural language interaction.**")
1251
+ with gr.Column(scale=1):
1252
+ u = gr.UploadButton("Upload a doc/excel", file_count="single", elem_classes="gr-buttonbig")
1253
+ #excel_file = gr.UploadButton("Upload an excel", file_count="single", elem_classes="gr-buttonbig", file_types=[".xlsx", ".xls"])
1254
+ with gr.Column(scale=1):
1255
+ add_button = gr.Button("Add to RedMindGPT", elem_classes="gr-buttonbig", visible=False)
1256
+ with gr.Row():
1257
+ title_textbox = gr.Textbox(label="Title", visible=False)
1258
+ summary_textarea = gr.Textbox(label="Summary", lines=5, visible=False)
1259
+
1260
 
1261
+ output_message = gr.Markdown() # Markdown to display output message
1262
+ success_message = gr.Markdown() # Placeholder for messages
1263
+
1264
+
1265
+ # Moved function calling lines to the end
1266
+ stop_button.click(stop_processing, [chatbot], [chatbot])
1267
+
1268
  button.click(handle_query, [message, chatbot], [chatbot])
1269
  message.submit(handle_query, [message, chatbot], [chatbot])
1270
  message.submit(lambda x: gr.update(value=""), None, [message], queue=False)
 
1274
  submit_feedback_button.click(submit_feedback, [feedback_textbox, chatbot], [chatbot, feedback_textbox, submit_feedback_button])
1275
  submit_feedback_button.click(lambda x: gr.update(value=''), [], [feedback_textbox])
1276
 
 
1277
  sample_button.click(handle_query, [sample_button, chatbot], [chatbot])
1278
  sample_button1.click(handle_query, [sample_button1, chatbot], [chatbot])
1279
  sample_button2.click(handle_query, [sample_button2, chatbot], [chatbot])
1280
  sample_button3.click(handle_query, [sample_button3, chatbot], [chatbot])
1281
  sample_button4.click(handle_query, [sample_button4, chatbot], [chatbot])
1282
 
1283
+ u.upload(upload_file, u, [title_textbox, summary_textarea])
1284
+ u.upload(lambda _: (gr.update(visible=True), gr.update(visible=True), gr.update(visible=True)), None, [title_textbox, summary_textarea, add_button])
1285
+ add_button.click(add_to_redmindgpt, [title_textbox, summary_textarea], output_message)
1286
+ add_button.click(lambda _: (gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)), None, [title_textbox, summary_textarea, add_button])
1287
+
1288
+ demo.launch(auth=[("lakshmi", "redmind"), ("arun", "redmind"), ("NewageGlobal", "Newage123$")], auth_message="RedMindGPT", inline=False)