rchrdgwr commited on
Commit
dacc583
β€’
1 Parent(s): be535f1
Files changed (30) hide show
  1. README copy.md +0 -12
  2. README.md +4 -3
  3. app.py +131 -144
  4. chainlit.md +1 -1
  5. classes.py +7 -1
  6. dashboard_server.py +0 -18
  7. dashboards/dashboard_04586f45c89443b3a7c26e295523cc70.html +0 -63
  8. dashboards/dashboard_057256deb39742fcaa24d4f529fcf20f.html +0 -63
  9. dashboards/dashboard_1fe6095d0e794299814937ab8bf8fd81.html +0 -63
  10. dashboards/dashboard_3a39eb7d2a124e8a98fb80e8c9e283e9.html +0 -63
  11. dashboards/dashboard_67eef223bccf445494d5d1e2980f92c4.html +0 -63
  12. dashboards/dashboard_6eb00dacfbce452695749b54a9473bda.html +0 -63
  13. dashboards/dashboard_6f0e941e245e4342a7d7742c96056e3e.html +0 -63
  14. dashboards/dashboard_8be5d87c4f254223886d6fc6fd20eb35.html +0 -63
  15. dashboards/dashboard_948bfae4ec42480fad75b2e0cdd3591d.html +0 -63
  16. dashboards/dashboard_acd7a6027b0d4e2397fb99ce5fa0861c.html +0 -63
  17. dashboards/dashboard_bfc79abe9a474092a98769c9ba96d71d.html +0 -63
  18. dashboards/dashboard_f00a8bbcff044f708de1daf93a73d74f.html +0 -63
  19. data/zzzSalesBuddy_Opportunities.csv +0 -7
  20. requirements.txt +6 -1
  21. static/dashboards/dashboard_0ec0b22e698c4db19e140257d9fa0f56.html +0 -63
  22. static/dashboards/dashboard_17b1f47a0e424c8c98551303bc9f44c5.html +0 -63
  23. static/dashboards/dashboard_2544c3a4c60249f4a231eac133e8e9e8.html +0 -63
  24. static/dashboards/dashboard_ca3b8724dfce419da3254aadacbc969d.html +0 -63
  25. static/dashboards/dashboard_f2a671e972a747cdb996dc84a8de9f5a.html +0 -63
  26. templates/dashboard_template.html +0 -52
  27. utils_data.py +1 -41
  28. utils_evaluate.py +80 -47
  29. utils_output.py +114 -20
  30. utils_prompt.py +76 -7
README copy.md DELETED
@@ -1,12 +0,0 @@
1
- ---
2
- title: SalesBuddy for BetterTech
3
- emoji: πŸ‘
4
- colorFrom: pink
5
- colorTo: blue
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- short_description: BetterTech Lending Analytics provides a comprehensive solution for real-time analysis in lending, surpassing basic regulatory compliance by enabling reporting, explaining, and optimizing. Deployed as SaaS, on-premise, or in the cloud, it empowers organizations to improve performance, enhance decision-making, and stay competitive by simulating various scenarios efficiently and accurately.
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -1,11 +1,12 @@
1
  ---
2
- title: SalesBuddy
3
- emoji: ⚑
4
  colorFrom: pink
5
- colorTo: indigo
6
  sdk: docker
7
  pinned: false
8
  license: mit
 
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: SalesBuddy for BetterTech
3
+ emoji: πŸ‘
4
  colorFrom: pink
5
+ colorTo: blue
6
  sdk: docker
7
  pinned: false
8
  license: mit
9
+ short_description: BetterTech Lending Analytics provides a comprehensive solution for real-time analysis in lending, surpassing basic regulatory compliance by enabling reporting, explaining, and optimizing. Deployed as SaaS, on-premise, or in the cloud, it empowers organizations to improve performance, enhance decision-making, and stay competitive by simulating various scenarios efficiently and accurately.
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,30 +1,31 @@
 
1
  import chainlit as cl
 
2
  import os
 
 
3
  from dotenv import load_dotenv
4
- import asyncio
5
- from langchain_core.runnables.config import RunnableConfig
6
  from langchain_openai import ChatOpenAI
7
- from datetime import datetime, timedelta
8
- import pyttsx3
9
- from tabulate import tabulate
10
  from utils_data import get_company_data, get_opportunities, get_questions, get_customer_background
11
- import json
12
  from utils_prompt import get_user_template, get_system_template
13
- from utils_evaluate import get_evaluation
14
  from utils_prompt import get_chat_prompt
15
- from classes import SessionState
16
- from utils_output import create_html_dashboard
17
- import threading
18
- import dashboard_server
19
 
20
- server_thread = threading.Thread(target=dashboard_server.run_server, daemon=True)
21
- server_thread.start()
22
-
23
- DASHBOARD_SERVER_URL = f"http://localhost:{dashboard_server.PORT}"
24
 
25
  load_dotenv()
26
  openai_api_key = os.getenv("OPENAI_API_KEY")
27
 
 
 
 
 
 
 
 
28
  @cl.action_callback("Run a Scenario")
29
  async def on_action(action):
30
  scenarios = get_opportunities()
@@ -45,29 +46,26 @@ async def on_action(action):
45
  f"({row['Customer Contact Role']})"
46
  )
47
  scenario_actions.append(scenario_action)
48
-
49
- # Send message with action buttons for the user to choose
50
  await cl.Message(content="Select a scenario (hover for details):", actions=scenario_actions).send()
51
 
52
  @cl.action_callback("Scenario")
53
  async def on_action(action):
54
- await cl.Message(content="Please wait, I am gathering the scenario information...").send()
55
  index = int(action.value)
56
  scenarios = cl.user_session.get("scenarios", None)
57
  if scenarios is None:
58
  await cl.Message(content="No scenarios found.").send()
59
  return
60
  await cl.Message(content="...gathering scenario information").send()
61
- # await asyncio.sleep(1)
62
 
63
  await cl.Message(content="...creating questions").send()
64
- # await asyncio.sleep(3)
65
- # get scenario, customer, company
66
  selected_scenario = scenarios.iloc[index]
67
  this_session = cl.user_session.get("session", None)
68
  this_session.add_scenario_info(selected_scenario)
69
  get_customer_background(this_session, selected_scenario['Customer Name'])
70
- # get questions
71
  this_session.questions = get_questions(this_session.opportunity.stage, this_session.num_questions)
72
 
73
  opening_message = this_session.get_opening()
@@ -82,38 +80,25 @@ async def on_action(action):
82
  this_session = cl.user_session.get("session", None)
83
  start_time = datetime.now()
84
  this_session.start_time = start_time
85
- await cl.Message(content=f"{this_session.customer.contact_name} joins the zoom call").send()
 
 
86
 
87
- # @cl.action_callback("ask question")
88
- # async def on_action(action):
89
- # print(questions_and_answers.columns)
90
- # print(questions_and_answers.head())
91
- # asked_question = cl.user_session.get("asked_question", 0)
92
- # question = questions_and_answers.iloc[asked_question]["Customer Question (Provided by Claude)"]
93
- # print(f"Question: {question}")
94
- # print(question)
95
- # asked_question += 1
96
- # cl.user_session.set("asked_question", asked_question)
97
- # cl.user_session.set("question", question)
98
-
99
- # message = f"The question will be: {question}"
100
- # await send_message(message)
101
- # await cl.Message(message).send()
102
-
103
- @cl.action_callback("evaluate")
104
  async def on_action(action):
105
- print("evaluation")
106
- cl.user_session.set("evaluation", "true")
107
- out_text = get_evaluation()
108
- await cl.Message(content=out_text).send()
109
-
110
- user_template = get_user_template()
111
- system_template = get_system_template()
112
 
113
- def speak_text(text):
114
- engine = pyttsx3.init(driverName='sapi5')
115
- engine.say(text)
116
- engine.runAndWait()
 
 
 
117
 
118
  #############################################
119
  ### On Chat Start (Session Start) Section ###
@@ -122,14 +107,13 @@ def speak_text(text):
122
  async def on_chat_start():
123
  this_session = SessionState()
124
  get_company_data(this_session)
125
- print(this_session)
126
  cl.user_session.set("session", this_session)
127
 
128
  cl.user_session.set("message_count", 0)
129
  cl.user_session.set("follow_up_questions", 0)
130
 
131
  chat_prompt = get_chat_prompt()
132
- chat_model = ChatOpenAI(model="gpt-4o-mini")
133
  simple_chain = chat_prompt | chat_model
134
  cl.user_session.set("chain", simple_chain)
135
 
@@ -137,49 +121,30 @@ async def on_chat_start():
137
  await cl.Message(content=welcome_message).send()
138
  await cl.Message(content=this_session.company.product_summary).send()
139
 
140
- misc_actions = [
141
- cl.Action(name="Run a Scenario", value="run-scenario", description="Run a scenario"),
142
- cl.Action(name="Evaluate", value="evaluate", description="Evaluate")
143
- ]
144
- await cl.Message(content="Select an action:", actions=misc_actions).send()
145
-
146
-
147
-
148
- # async def send_message(question):
149
- # history = cl.user_session.get("history", [])
150
- # message_count = cl.user_session.get("message_count", 0)
151
- # message_count += 1
152
- # cl.user_session.set("message_count", message_count)
153
- # chain = cl.user_session.get("chain")
154
- # company = cl.user_session.get("company", "Acme Corp")
155
- # role = cl.user_session.get("role", "ceo")
156
- # attitude = cl.user_session.get("attitude", "happy")
157
- # personality = cl.user_session.get("personality", "sarcastic")
158
- # twist = cl.user_session.get("twist", "")
159
- # answer = "123"
160
- # follow_up_questions = cl.user_session.get("follow_up_questions", 0)
161
- # follow_up_questions += 1
162
- # cl.user_session.set("follow_up_questions", follow_up_questions)
163
-
164
- # if message_count == 2:
165
- # twist = "The fire alarm is going off"
166
- # msg = cl.Message(content="")
167
-
168
- # history.append({"role": "user", "content": question})
169
- # # handle streaming of LLM responses
170
- # response_content = ""
171
 
172
- # async for chunk in chain.astream(
173
- # {"question": question, "company": company, "role": role, "attitude": attitude, "twist": twist, "conversation_history": history, "personality": personality, "answer": answer, "follow_up_questions": follow_up_questions },
174
- # config=RunnableConfig(callbacks=[cl.LangchainCallbackHandler()]),
175
- # ):
176
- # response_content += chunk.content
177
- # await msg.stream_token(chunk.content)
178
- # speak_text(response_content)
179
- # history.append({"role": "assistant", "content": response_content})
180
- # cl.user_session.set("history", history)
181
- # await msg.send()
182
 
 
 
 
183
  @cl.on_message
184
  async def main(message: cl.Message):
185
  content = message.content.strip()
@@ -191,99 +156,127 @@ async def main(message: cl.Message):
191
 
192
  else:
193
  if this_session.status == "active":
194
-
195
  chain = cl.user_session.get("chain")
196
-
197
  history = cl.user_session.get("history", [])
198
  history.append({"role": "user", "content": message})
199
  this_session.previous_answer = message.content
200
-
201
  prompt_parm = prepare_chain_parameters(this_session, message, history)
202
- # handle streaming of LLM responses
203
  response_content = chain.invoke(prompt_parm)
204
  json_str = response_content.content.strip('```json\n').strip('```')
205
- this_response = json.loads(json_str)
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  if this_session.question != "":
207
  this_session.responses.append({
208
  "question_number": this_session.current_question_index,
209
  "question": this_session.question,
210
  "response": this_session.rep_answer,
211
  "ground_truth": this_session.ground_truth,
212
- "response_score": this_response.get("Score"),
213
- "response_evaluation": this_response.get("Evaluation"),
214
- "mood_score": this_response.get("Mood Score"),
215
- "overall_evaluation": this_response.get("Overall Evaluation"),
 
216
  })
217
-
218
- await cl.Message(response_content.content).send()
 
 
 
 
219
 
220
  history.append({"role": "assistant", "content": response_content})
221
  cl.user_session.set("history", history)
222
  this_session.current_question_index += 1
223
  if this_session.current_question_index > len(this_session.questions):
224
  this_session.status = "complete"
225
- else:
226
- out_text = "All questions answered. Preparing evaluation results..."
227
- await cl.Message(content=out_text).send()
228
- await asyncio.sleep(1)
229
- dashboard_path = create_html_dashboard(this_session.responses)
230
- dashboard_filename = create_html_dashboard(this_session.responses)
231
-
232
- # Create a link to the dashboard
233
- dashboard_link = f"{DASHBOARD_SERVER_URL}/{dashboard_filename}"
234
- print(dashboard_link)
235
- await cl.Message(content="View the latest Response Dashboard:").send()
236
- # await cl.Link(url=dashboard_link, label="Response Dashboard", target="_blank").send()
237
- await cl.Message(content=f"View the [Evaluation Dashboard]({dashboard_link})").send()
238
-
239
 
240
- def display_responses(responses):
241
- table_data = []
242
- for resp in responses:
243
- table_data.append([
244
- resp["question_number"],
245
- resp["question"],
246
- resp["response"],
247
- resp["ground_truth"],
248
- resp["response_score"],
249
- resp["response_evaluation"],
250
- resp["mood_score"],
251
- resp["overall_evaluation"]
252
- ])
253
- return table_data
 
 
 
 
254
 
255
  def prepare_chain_parameters(this_session, message, history):
256
- print("")
257
- print("prepare_chain_parameters()")
258
- print(message.content)
259
  message = message.content
260
  previous_question = ""
261
  rep_answer = ""
262
  next_question = ""
263
  ground_truth = ""
 
264
  if this_session.current_question_index == 0:
265
  previous_question = ""
266
  rep_answer = ""
267
  ground_truth = ""
268
  next_question = this_session.questions[this_session.current_question_index]["question"]
 
269
  elif this_session.current_question_index >= len(this_session.questions):
270
  next_question = ""
271
  previous_question = this_session.questions[this_session.current_question_index - 1]["question"]
272
  rep_answer = this_session.previous_answer
273
  ground_truth = this_session.questions[this_session.current_question_index - 1]["ground_truth"]
 
 
 
 
 
 
274
  else:
275
  previous_question = this_session.questions[this_session.current_question_index - 1]["question"]
276
  rep_answer = this_session.previous_answer
277
  next_question = this_session.questions[this_session.current_question_index]["question"]
278
  ground_truth = this_session.questions[this_session.current_question_index]["ground_truth"]
 
279
  this_session.ground_truth = ground_truth
280
  this_session.question = previous_question
281
  this_session.rep_answer = rep_answer
 
 
282
  print("Sending the following:")
 
283
  print(f"Previous question: {previous_question}")
284
  print(f"Rep answer: {rep_answer}")
285
  print(f"Next question: {next_question}")
286
- print(f"Message: {message}")
287
  rep_company_details = f"""
288
  Name: {this_session.company.name}
289
  Description: {this_session.company.description}
@@ -317,6 +310,7 @@ def prepare_chain_parameters(this_session, message, history):
317
  "next_question": next_question,
318
  "rep_answer": rep_answer,
319
  "conversation_history": history,
 
320
  }
321
  return parm
322
 
@@ -325,12 +319,9 @@ async def handle_control_message(command: str):
325
  main_command = command_parts[0].lower()
326
 
327
  if main_command == 'start':
328
- # Handle start command
329
  await cl.Message(content="Starting new session...").send()
330
- # Add your session start logic here
331
 
332
  elif main_command == 'stop':
333
- # Handle end command
334
  this_session = cl.user_session.get("session")
335
  end_time = datetime.now()
336
  duration = end_time - this_session.start_time
@@ -339,14 +330,10 @@ async def handle_control_message(command: str):
339
  this_session.duration_minutes = duration_minutes
340
 
341
  await cl.Message(content=f"Ending current session after {this_session.duration_minutes} minutes").send()
342
-
343
- # Add your session end logic here
344
  elif main_command == 'pause':
345
- # Handle end command
346
  await cl.Message(content="Ending current session...").send()
347
 
348
  elif main_command == 'time':
349
- # Handle time command (display current session duration)
350
  this_session = cl.user_session.get("session")
351
  duration = this_session.get_session_duration()
352
  await cl.Message(content=f"Current session duration: {duration}").send()
 
1
+ import asyncio
2
  import chainlit as cl
3
+ import json
4
  import os
5
+ from classes import SessionState
6
+ from datetime import datetime
7
  from dotenv import load_dotenv
 
 
8
  from langchain_openai import ChatOpenAI
 
 
 
9
  from utils_data import get_company_data, get_opportunities, get_questions, get_customer_background
 
10
  from utils_prompt import get_user_template, get_system_template
 
11
  from utils_prompt import get_chat_prompt
12
+ from utils_output import display_evaluation_results, display_llm_responses
 
 
 
13
 
14
+ llm_model = "gpt-4o-mini"
15
+ # llm_model = "gpt-4o"
16
+ # llm_model = "gpt-3.5-turbo"
17
+ # llm_model = "gpt-4o-2024-08-06"
18
 
19
  load_dotenv()
20
  openai_api_key = os.getenv("OPENAI_API_KEY")
21
 
22
+ user_template = get_user_template()
23
+ system_template = get_system_template()
24
+
25
+ #############################################
26
+ # Action callbacks
27
+ #############################################
28
+
29
  @cl.action_callback("Run a Scenario")
30
  async def on_action(action):
31
  scenarios = get_opportunities()
 
46
  f"({row['Customer Contact Role']})"
47
  )
48
  scenario_actions.append(scenario_action)
 
 
49
  await cl.Message(content="Select a scenario (hover for details):", actions=scenario_actions).send()
50
 
51
  @cl.action_callback("Scenario")
52
  async def on_action(action):
53
+ await cl.Message(content="Please wait, I am gathering information...").send()
54
  index = int(action.value)
55
  scenarios = cl.user_session.get("scenarios", None)
56
  if scenarios is None:
57
  await cl.Message(content="No scenarios found.").send()
58
  return
59
  await cl.Message(content="...gathering scenario information").send()
60
+ await asyncio.sleep(1)
61
 
62
  await cl.Message(content="...creating questions").send()
63
+ await asyncio.sleep(1)
64
+
65
  selected_scenario = scenarios.iloc[index]
66
  this_session = cl.user_session.get("session", None)
67
  this_session.add_scenario_info(selected_scenario)
68
  get_customer_background(this_session, selected_scenario['Customer Name'])
 
69
  this_session.questions = get_questions(this_session.opportunity.stage, this_session.num_questions)
70
 
71
  opening_message = this_session.get_opening()
 
80
  this_session = cl.user_session.get("session", None)
81
  start_time = datetime.now()
82
  this_session.start_time = start_time
83
+ output = f"{this_session.customer.contact_name} joins the zoom call"
84
+ print(output)
85
+ await cl.Message(content=output).send()
86
 
87
+ @cl.action_callback("Evaluate Performance")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  async def on_action(action):
89
+ this_session = cl.user_session.get("session", None)
90
+ if this_session is None:
91
+ await cl.Message(content="No session found.").send()
92
+ return
93
+ await display_evaluation_results(cl, this_session)
 
 
94
 
95
+ @cl.action_callback("Display Queries and Responses")
96
+ async def on_action(action):
97
+ this_session = cl.user_session.get("session", None)
98
+ if this_session is None:
99
+ await cl.Message(content="No session found.").send()
100
+ return
101
+ await display_llm_responses(cl, this_session)
102
 
103
  #############################################
104
  ### On Chat Start (Session Start) Section ###
 
107
  async def on_chat_start():
108
  this_session = SessionState()
109
  get_company_data(this_session)
 
110
  cl.user_session.set("session", this_session)
111
 
112
  cl.user_session.set("message_count", 0)
113
  cl.user_session.set("follow_up_questions", 0)
114
 
115
  chat_prompt = get_chat_prompt()
116
+ chat_model = ChatOpenAI(model=llm_model)
117
  simple_chain = chat_prompt | chat_model
118
  cl.user_session.set("chain", simple_chain)
119
 
 
121
  await cl.Message(content=welcome_message).send()
122
  await cl.Message(content=this_session.company.product_summary).send()
123
 
124
+ scenarios = get_opportunities()
125
+ cl.user_session.set("scenarios", scenarios)
126
+ scenarios = cl.user_session.get("scenarios", None)
127
+ if scenarios is None:
128
+ await cl.Message(content="No scenarios found.").send()
129
+ return
130
+
131
+ scenario_actions = []
132
+ for idx, row in scenarios.iterrows():
133
+ if row['Opportunity Description'] != "":
134
+ scenario_action = cl.Action(
135
+ name="Scenario",
136
+ value=f"{idx}", # Send the row index as value
137
+ description=f"{row['Customer Name']}: {row['Opportunity Name']} ({row['Opportunity Stage']}) "
138
+ f"Value: {row['Opportunity Value']}. Meeting with {row['Customer Contact']} "
139
+ f"({row['Customer Contact Role']})"
140
+ )
141
+ scenario_actions.append(scenario_action)
142
+ await cl.Message(content="Select a scenario (hover for details):", actions=scenario_actions).send()
 
 
 
 
 
 
 
 
 
 
 
 
143
 
 
 
 
 
 
 
 
 
 
 
144
 
145
+ #########################################################
146
+ ### On Message Section - called for each User Message ###
147
+ #########################################################
148
  @cl.on_message
149
  async def main(message: cl.Message):
150
  content = message.content.strip()
 
156
 
157
  else:
158
  if this_session.status == "active":
 
159
  chain = cl.user_session.get("chain")
 
160
  history = cl.user_session.get("history", [])
161
  history.append({"role": "user", "content": message})
162
  this_session.previous_answer = message.content
 
163
  prompt_parm = prepare_chain_parameters(this_session, message, history)
164
+ this_session.queries.append(prompt_parm)
165
  response_content = chain.invoke(prompt_parm)
166
  json_str = response_content.content.strip('```json\n').strip('```')
167
+ try:
168
+ this_response = json.loads(json_str)
169
+ except json.JSONDecodeError as e:
170
+ print(f"JSON Decode Error: {e}")
171
+ print(response_content.content)
172
+ print(f"Error at position {e.pos}: {json_str[max(0, e.pos-10):e.pos+10]}")
173
+ this_response = {"Response": "Error receiving response from LLM"}
174
+ llm_response = this_response.get("Response", "No response from LLM")
175
+ print("LLM Response:")
176
+ print(llm_response)
177
+ this_session.llm_responses.append(this_response)
178
+ print("Next question:")
179
+ print(this_response.get("Question", "No question"))
180
+
181
  if this_session.question != "":
182
  this_session.responses.append({
183
  "question_number": this_session.current_question_index,
184
  "question": this_session.question,
185
  "response": this_session.rep_answer,
186
  "ground_truth": this_session.ground_truth,
187
+ "response_score": this_response.get("Score", "No score"),
188
+ "response_evaluation": this_response.get("Evaluation", "No evaluation"),
189
+ "mood_score": this_response.get("Mood Score", "No mood score"),
190
+ "overall_score": this_response.get("Overall Score", "No overall score"),
191
+ "overall_evaluation": this_response.get("Overall Evaluation", "No overall evaluation"),
192
  })
193
+ message_to_rep = llm_response + "\n\n" + this_response.get("Question", "No question")
194
+ if this_session.do_voice:
195
+ print(f"Voice Response: {message_to_rep}")
196
+ else:
197
+ await cl.Message(message_to_rep).send()
198
+ # await cl.Message(this_response).send()
199
 
200
  history.append({"role": "assistant", "content": response_content})
201
  cl.user_session.set("history", history)
202
  this_session.current_question_index += 1
203
  if this_session.current_question_index > len(this_session.questions):
204
  this_session.status = "complete"
205
+ end_time = datetime.now()
206
+ duration = end_time - this_session.start_time
207
+ duration_minutes = round(duration.total_seconds() / 60)
208
+ this_session.end_time = end_time
209
+ this_session.duration_minutes = duration_minutes
210
+
211
+ if this_session.do_evaluation:
212
+ await display_evaluation_results(cl, this_session)
213
+ else:
214
+ evaluate_actions = [
215
+ cl.Action(name="Evaluate Performance", value="evaluate", description="Evaluate Performance"),
216
+ cl.Action(name="Display Queries and Responses", value="display_llm_responses", description="Display LLM Responses")
217
+ ]
218
+ await cl.Message(content="Click to evaluate", actions=evaluate_actions).send()
219
 
220
+ #############################################
221
+ ### Support Functions
222
+ #############################################
223
+
224
+ # def display_responses(responses):
225
+ # table_data = []
226
+ # for resp in responses:
227
+ # table_data.append([
228
+ # resp["question_number"],
229
+ # resp["question"],
230
+ # resp["response"],
231
+ # resp["ground_truth"],
232
+ # resp["response_score"],
233
+ # resp["response_evaluation"],
234
+ # resp["mood_score"],
235
+ # resp["overall_evaluation"]
236
+ # ])
237
+ # return table_data
238
 
239
  def prepare_chain_parameters(this_session, message, history):
 
 
 
240
  message = message.content
241
  previous_question = ""
242
  rep_answer = ""
243
  next_question = ""
244
  ground_truth = ""
245
+ command = ""
246
  if this_session.current_question_index == 0:
247
  previous_question = ""
248
  rep_answer = ""
249
  ground_truth = ""
250
  next_question = this_session.questions[this_session.current_question_index]["question"]
251
+ command = "You should greet the rep"
252
  elif this_session.current_question_index >= len(this_session.questions):
253
  next_question = ""
254
  previous_question = this_session.questions[this_session.current_question_index - 1]["question"]
255
  rep_answer = this_session.previous_answer
256
  ground_truth = this_session.questions[this_session.current_question_index - 1]["ground_truth"]
257
+ command = """Thank the customer, offer a comment on the answer and overall performance.
258
+ Conclude the conversation with a summary and give a farewell.
259
+ If the answers were good, give a positive farewell and offer a follow up meeting.
260
+ If the answers were poor, give a poor farewell.
261
+ You can add additional comments as needed.
262
+ """
263
  else:
264
  previous_question = this_session.questions[this_session.current_question_index - 1]["question"]
265
  rep_answer = this_session.previous_answer
266
  next_question = this_session.questions[this_session.current_question_index]["question"]
267
  ground_truth = this_session.questions[this_session.current_question_index]["ground_truth"]
268
+ command = "You should respond to the answer based on how well the rep answered the previous question."
269
  this_session.ground_truth = ground_truth
270
  this_session.question = previous_question
271
  this_session.rep_answer = rep_answer
272
+ print("--------------------------------")
273
+ print(f"Message: {message}")
274
  print("Sending the following:")
275
+ print(f"Command: {command}")
276
  print(f"Previous question: {previous_question}")
277
  print(f"Rep answer: {rep_answer}")
278
  print(f"Next question: {next_question}")
279
+
280
  rep_company_details = f"""
281
  Name: {this_session.company.name}
282
  Description: {this_session.company.description}
 
310
  "next_question": next_question,
311
  "rep_answer": rep_answer,
312
  "conversation_history": history,
313
+ "command": command,
314
  }
315
  return parm
316
 
 
319
  main_command = command_parts[0].lower()
320
 
321
  if main_command == 'start':
 
322
  await cl.Message(content="Starting new session...").send()
 
323
 
324
  elif main_command == 'stop':
 
325
  this_session = cl.user_session.get("session")
326
  end_time = datetime.now()
327
  duration = end_time - this_session.start_time
 
330
  this_session.duration_minutes = duration_minutes
331
 
332
  await cl.Message(content=f"Ending current session after {this_session.duration_minutes} minutes").send()
 
 
333
  elif main_command == 'pause':
 
334
  await cl.Message(content="Ending current session...").send()
335
 
336
  elif main_command == 'time':
 
337
  this_session = cl.user_session.get("session")
338
  duration = this_session.get_session_duration()
339
  await cl.Message(content=f"Current session duration: {duration}").send()
chainlit.md CHANGED
@@ -1,2 +1,2 @@
1
- # Sideckick POC
2
 
 
1
+ # Sales Buddy
2
 
classes.py CHANGED
@@ -1,4 +1,6 @@
1
  class SessionState:
 
 
2
  status = "active"
3
  scenario = None
4
  qa_mode = "single"
@@ -8,13 +10,17 @@ class SessionState:
8
  duration_minutes = None
9
  attitude = "Happy"
10
  mood_score = 5
11
- num_questions = 2
12
  current_question_index = 0
13
  previous_answer = None
14
  question = ""
15
  ground_truth = ""
16
  rep_answer = ""
17
  responses = []
 
 
 
 
18
  class Company:
19
  def __init__(self, name, description, product, product_summary, product_description):
20
  self.name = name
 
1
  class SessionState:
2
+ do_evaluation = False
3
+ do_voice = False
4
  status = "active"
5
  scenario = None
6
  qa_mode = "single"
 
10
  duration_minutes = None
11
  attitude = "Happy"
12
  mood_score = 5
13
+ num_questions = 1
14
  current_question_index = 0
15
  previous_answer = None
16
  question = ""
17
  ground_truth = ""
18
  rep_answer = ""
19
  responses = []
20
+ queries = []
21
+ llm_responses = []
22
+ command = ""
23
+ scores = []
24
  class Company:
25
  def __init__(self, name, description, product, product_summary, product_description):
26
  self.name = name
dashboard_server.py DELETED
@@ -1,18 +0,0 @@
1
- import http.server
2
- import socketserver
3
- import os
4
-
5
- PORT = 8080
6
- DIRECTORY = "dashboards"
7
-
8
- class Handler(http.server.SimpleHTTPRequestHandler):
9
- def __init__(self, *args, **kwargs):
10
- super().__init__(*args, directory=DIRECTORY, **kwargs)
11
-
12
- def run_server():
13
- with socketserver.TCPServer(("", PORT), Handler) as httpd:
14
- print(f"Serving dashboards at port {PORT}")
15
- httpd.serve_forever()
16
-
17
- if __name__ == "__main__":
18
- run_server()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_04586f45c89443b3a7c26e295523cc70.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>0</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td></td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>1</td>
52
- <td></td>
53
- <td></td>
54
- <td>Our customers have to consider annual running costs (consumption), one time implementation fee, training costs, and support costs as they come on to our platform. Customers have cited productivity gains of 25% and analytics costs going down by 30% within 18 months post implementation. </td>
55
- <td>1</td>
56
- <td>The response was not helpful or informative. It provided no relevant information regarding the total cost of ownership, which is crucial for my decision-making process.</td>
57
- <td>5</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_057256deb39742fcaa24d4f529fcf20f.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, thanks for reaching out! I'm interested to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hi Tony, I appreciate your response, but it seems I didn't get the specific details I was looking for regarding the total cost of ownership for your solution. Could you provide me with a breakdown of that information?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response did not provide any useful information about the total cost of ownership. It was vague and unhelpful.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_1fe6095d0e794299814937ab8bf8fd81.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>0</td>
41
- <td></td>
42
- <td></td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>1</td>
52
- <td>What's the total cost of ownership for your solution?</td>
53
- <td>dsf</td>
54
- <td>Our customers have to consider annual running costs (consumption), one time implementation fee, training costs, and support costs as they come on to our platform. Customers have cited productivity gains of 25% and analytics costs going down by 30% within 18 months post implementation. </td>
55
- <td>1</td>
56
- <td>The response did not provide any relevant information regarding the total cost of ownership for the solution. Therefore, I cannot consider this a satisfactory answer.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_3a39eb7d2a124e8a98fb80e8c9e283e9.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, I'm doing well, thank you! I have a question: What's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Thank you for the information, Tony! It helps to have clarity on the cost.</td>
54
- <td></td>
55
- <td>5</td>
56
- <td>The answer was straightforward and provided the requested information clearly. However, it lacks additional context or breakdown regarding what the cost includes, which could have been beneficial.</td>
57
- <td>5</td>
58
- <td>5</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_67eef223bccf445494d5d1e2980f92c4.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hello Tony! I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td></td>
45
- <td></td>
46
- <td>5</td>
47
- <td></td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Thank you for your response, Tony. However, I was expecting more detailed information about the total cost of ownership for your solution. Can you provide further clarification on that?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response was vague and did not provide any numerical or contextual information about the total cost of ownership. It appears as a misunderstanding or an error in communication.</td>
57
- <td>5</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_6eb00dacfbce452695749b54a9473bda.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hello Tony! I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hello Tony! I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
54
- <td></td>
55
- <td>None</td>
56
- <td>The response provided does not contain any relevant information regarding the total cost of ownership for the solution. It seems to be incomplete or not related to the question asked.</td>
57
- <td>5</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_6f0e941e245e4342a7d7742c96056e3e.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, I'm doing well, thank you! I have a question: What's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Thank you for the information, Tony! It helps to have clarity on the cost.</td>
54
- <td></td>
55
- <td>5</td>
56
- <td>The answer was straightforward and provided the requested information clearly. However, it lacks additional context or breakdown regarding what the cost includes, which could have been beneficial.</td>
57
- <td>5</td>
58
- <td>5</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_8be5d87c4f254223886d6fc6fd20eb35.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hello Tony! I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td></td>
45
- <td></td>
46
- <td>5</td>
47
- <td></td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Thank you for your response, Tony. However, I was expecting more detailed information about the total cost of ownership for your solution. Can you provide further clarification on that?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response was vague and did not provide any numerical or contextual information about the total cost of ownership. It appears as a misunderstanding or an error in communication.</td>
57
- <td>5</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_948bfae4ec42480fad75b2e0cdd3591d.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>0</td>
41
- <td></td>
42
- <td></td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>1</td>
52
- <td>What's the total cost of ownership for your solution?</td>
53
- <td>dsf</td>
54
- <td>Our customers have to consider annual running costs (consumption), one time implementation fee, training costs, and support costs as they come on to our platform. Customers have cited productivity gains of 25% and analytics costs going down by 30% within 18 months post implementation. </td>
55
- <td>1</td>
56
- <td>The response did not provide any relevant information regarding the total cost of ownership for the solution. Therefore, I cannot consider this a satisfactory answer.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_acd7a6027b0d4e2397fb99ce5fa0861c.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, thanks for reaching out! I'm interested to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hi Tony, I appreciate your response, but it seems I didn't get the specific details I was looking for regarding the total cost of ownership for your solution. Could you provide me with a breakdown of that information?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response did not provide any useful information about the total cost of ownership. It was vague and unhelpful.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_bfc79abe9a474092a98769c9ba96d71d.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hello Tony! I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hello Tony! I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
54
- <td></td>
55
- <td>None</td>
56
- <td>The response provided does not contain any relevant information regarding the total cost of ownership for the solution. It seems to be incomplete or not related to the question asked.</td>
57
- <td>5</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboards/dashboard_f00a8bbcff044f708de1daf93a73d74f.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>0</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td></td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>1</td>
52
- <td></td>
53
- <td></td>
54
- <td>Our customers have to consider annual running costs (consumption), one time implementation fee, training costs, and support costs as they come on to our platform. Customers have cited productivity gains of 25% and analytics costs going down by 30% within 18 months post implementation. </td>
55
- <td>1</td>
56
- <td>The response was not helpful or informative. It provided no relevant information regarding the total cost of ownership, which is crucial for my decision-making process.</td>
57
- <td>5</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
data/zzzSalesBuddy_Opportunities.csv DELETED
@@ -1,7 +0,0 @@
1
- Opportunity ID,Customer Name,Opportunity Name,Opportunity Stage,Opportunity Description,Opportunity Value,Close Date,Customer Contact,Customer Contact Role,Activity,Next Steps
2
- XFR0001,HSBC,Lending - Loan Origination System,Proposal,Developing analytic capabilities for the loan origination system,"$250,000",11/30/2024,John Smith,"VP, Information Technology",Met John on 9/16. Product demo went well and pricing was submitted. We have discussed the value proposition of our solution and John's team agrees that our solution's real time analytic capabilities will provide them the ability to improve their credit decisioning process,Meet with John on 10/12 to discuss pricing
3
- XFR0002,Capital One,,,,,,,,,
4
- XFR0003,HSBC,,,,,,,,,
5
- XFR0004,PNC Bank,,,,,,,,,
6
- XFR0005,,,,,,,,,,
7
- XFR0006,,,,,,,,,,
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -9,4 +9,9 @@ comtypes==1.2.0
9
  pandas==2.1.4
10
  tabulate==0.9.0
11
  gdown==4.7.1
12
- Jinja2==3.1.2
 
 
 
 
 
 
9
  pandas==2.1.4
10
  tabulate==0.9.0
11
  gdown==4.7.1
12
+ Jinja2==3.1.2
13
+ datasets==2.14.5
14
+ ragas==0.1.0
15
+ nltk==3.9.1
16
+ rouge-score==0.1.2
17
+ sentence-transformers==2.3.0
static/dashboards/dashboard_0ec0b22e698c4db19e140257d9fa0f56.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, thanks for reaching out! Could you tell me what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hi Tony, thanks for your response! I noticed that you didn't provide any specific details about the total cost of ownership. Can you clarify that for me?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response did not provide any useful information regarding the total cost of ownership, which is crucial for my decision-making process. The lack of clarity is disappointing.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/dashboards/dashboard_17b1f47a0e424c8c98551303bc9f44c5.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hello Tony, I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hello Tony, I hope you're doing well. I would like to know what's the total cost of ownership for your solution?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response was unhelpful and did not address my question about the total cost of ownership. It seems that there was a misunderstanding or an error in communication.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/dashboards/dashboard_2544c3a4c60249f4a231eac133e8e9e8.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, nice to connect! I wanted to ask, what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td></td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hi Tony, nice to connect! I wanted to ask, what's the total cost of ownership for your solution?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response was not satisfactory as it did not provide any information regarding the total cost of ownership. It simply stated '434', which is unclear and unhelpful. This leaves me without the necessary information to evaluate the solution's affordability and overall value.</td>
57
- <td>4</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/dashboards/dashboard_ca3b8724dfce419da3254aadacbc969d.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, thanks for reaching out. I'm interested in understanding the total cost of ownership for your solution.</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hi Tony, thanks for your response. However, I believe there may have been a misunderstanding regarding the total cost of ownership for your solution. It typically includes not just the initial purchase price but also maintenance, support, and other associated costs over time. Could you clarify that for me?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The response provided by the rep is insufficient and overly simplistic. A total cost of ownership should encompass multiple factors, not just a single dollar amount, which indicates a lack of thoroughness and understanding of customer needs.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/dashboards/dashboard_f2a671e972a747cdb996dc84a8de9f5a.html DELETED
@@ -1,63 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
-
39
- <tr>
40
- <td>1</td>
41
- <td>What's the total cost of ownership for your solution?</td>
42
- <td>Hi Tony, thanks for reaching out! I would like to know what's the total cost of ownership for your solution?</td>
43
- <td></td>
44
- <td>None</td>
45
- <td>None</td>
46
- <td>5</td>
47
- <td>None</td>
48
- </tr>
49
-
50
- <tr>
51
- <td>2</td>
52
- <td></td>
53
- <td>Hi Tony, thanks for your response. Can you clarify what the total cost of ownership for your solution includes?</td>
54
- <td></td>
55
- <td>1</td>
56
- <td>The answer provided is unclear and does not address my question about the total cost of ownership. It lacks detail and context, making it difficult to evaluate the solution's financial implications.</td>
57
- <td>3</td>
58
- <td>1</td>
59
- </tr>
60
-
61
- </table>
62
- </body>
63
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
templates/dashboard_template.html DELETED
@@ -1,52 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Response Dashboard</title>
7
- <style>
8
- table {
9
- border-collapse: collapse;
10
- width: 100%;
11
- }
12
- th, td {
13
- border: 1px solid #ddd;
14
- padding: 8px;
15
- text-align: left;
16
- }
17
- th {
18
- background-color: #f2f2f2;
19
- }
20
- tr:nth-child(even) {
21
- background-color: #f9f9f9;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Response Dashboard</h1>
27
- <table>
28
- <tr>
29
- <th>#</th>
30
- <th>Question</th>
31
- <th>Response</th>
32
- <th>Ground Truth</th>
33
- <th>Score</th>
34
- <th>Evaluation</th>
35
- <th>Mood Score</th>
36
- <th>Overall Evaluation</th>
37
- </tr>
38
- {% for response in responses %}
39
- <tr>
40
- <td>{{ response.question_number }}</td>
41
- <td>{{ response.question }}</td>
42
- <td>{{ response.response }}</td>
43
- <td>{{ response.ground_truth }}</td>
44
- <td>{{ response.response_score }}</td>
45
- <td>{{ response.response_evaluation }}</td>
46
- <td>{{ response.mood_score }}</td>
47
- <td>{{ response.overall_evaluation }}</td>
48
- </tr>
49
- {% endfor %}
50
- </table>
51
- </body>
52
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
utils_data.py CHANGED
@@ -1,7 +1,6 @@
1
  import pandas as pd
2
  import os
3
 
4
-
5
  def get_questions(stage=None, num_questions=0):
6
  q_and_a_filename = "AIE4_SalesBuddy_QandA.csv"
7
  data = read_csv_from_data_folder(q_and_a_filename)
@@ -15,23 +14,13 @@ def get_questions(stage=None, num_questions=0):
15
  question = {
16
  'stage': row['Stage'],
17
  'question': row['Customer Question (Provided by Claude)'],
18
- # 'salesperson_response': row['Salesperson Response (Provided by Claude)'],
19
  'ground_truth': row['Ground Truth (Provided by Nitin). Marked as Salesperson 2 by Claude'],
20
- # 'salesperson_rating': row['Rating of Salesperson response (per Claude)'],
21
- # 'expert_rating': row['Rating of Groundtruth (per Claude)'],
22
- # 'comments': row['Comments (per Claude)']
23
  }
24
  if num_questions == 0 or num_questions > len(questions):
25
  print(f"Adding question: {question['question']}")
26
  questions.append(question)
27
  print(f"Returned {len(questions)} questions for stage {stage}")
28
  return questions
29
- # co = [
30
- # {"QID": 1, 'Question': 'What is your product?', 'Ground Truth': 'Our product is a CRM software.'},
31
- # {"QID": 2, 'Question': 'How much does it cost?', 'Ground Truth': 'It costs $99 per month.'},
32
- # {"QID": 3, 'Question': 'What are the key features?', 'Ground Truth': 'Key features include contact management, sales tracking, and reporting.'}
33
- # ]
34
- # return co
35
 
36
  def get_customer_background(scenario, customer_name="HSBC" ):
37
  background_filename = f"{customer_name}_background.txt"
@@ -40,7 +29,6 @@ def get_customer_background(scenario, customer_name="HSBC" ):
40
  print(f"Read background for {customer_name} - {background_filename}")
41
 
42
  def get_company_data(scenario):
43
-
44
  company = {
45
  "name": "BetterTech",
46
  "description": """
@@ -140,20 +128,7 @@ def get_opportunities():
140
  data = read_csv_from_data_folder(opportunities_filename)
141
  return data
142
 
143
-
144
-
145
  def read_csv_from_data_folder(filename, handle_nan='drop'):
146
- """
147
- Read a CSV file from the 'data' folder or Google Drive, and handle NaN values.
148
-
149
- Args:
150
- filename (str): The name of the CSV file to read.
151
- google_drive_id (str): The Google Drive file ID. If provided, it will be used if local file is not found.
152
- handle_nan (str): Method to handle NaN values. Options: 'drop', 'fill_na', 'fill_empty'. Default is 'drop'.
153
-
154
- Returns:
155
- pandas.DataFrame: The contents of the CSV file as a DataFrame with NaN values handled.
156
- """
157
  data_folder = "./data/"
158
  file_path = os.path.join(data_folder, filename)
159
 
@@ -184,15 +159,6 @@ def read_csv_from_data_folder(filename, handle_nan='drop'):
184
  return None
185
 
186
  def read_txt_from_data_folder(filename):
187
- """
188
- Read a text file from the 'data' folder.
189
-
190
- Args:
191
- filename (str): The name of the text file to read.
192
-
193
- Returns:
194
- str: The contents of the text file as a string.
195
- """
196
  data_folder = "./data/"
197
  file_path = os.path.join(data_folder, filename)
198
 
@@ -208,10 +174,4 @@ def read_txt_from_data_folder(filename):
208
  print(f"An error occurred while reading '{filename}': {str(e)}")
209
  return None
210
 
211
-
212
-
213
-
214
- if __name__ == "__main__":
215
- q_and_a_data = get_q_and_a()
216
- if q_and_a_data is not None:
217
- print(q_and_a_data.head())
 
1
  import pandas as pd
2
  import os
3
 
 
4
  def get_questions(stage=None, num_questions=0):
5
  q_and_a_filename = "AIE4_SalesBuddy_QandA.csv"
6
  data = read_csv_from_data_folder(q_and_a_filename)
 
14
  question = {
15
  'stage': row['Stage'],
16
  'question': row['Customer Question (Provided by Claude)'],
 
17
  'ground_truth': row['Ground Truth (Provided by Nitin). Marked as Salesperson 2 by Claude'],
 
 
 
18
  }
19
  if num_questions == 0 or num_questions > len(questions):
20
  print(f"Adding question: {question['question']}")
21
  questions.append(question)
22
  print(f"Returned {len(questions)} questions for stage {stage}")
23
  return questions
 
 
 
 
 
 
24
 
25
  def get_customer_background(scenario, customer_name="HSBC" ):
26
  background_filename = f"{customer_name}_background.txt"
 
29
  print(f"Read background for {customer_name} - {background_filename}")
30
 
31
  def get_company_data(scenario):
 
32
  company = {
33
  "name": "BetterTech",
34
  "description": """
 
128
  data = read_csv_from_data_folder(opportunities_filename)
129
  return data
130
 
 
 
131
  def read_csv_from_data_folder(filename, handle_nan='drop'):
 
 
 
 
 
 
 
 
 
 
 
132
  data_folder = "./data/"
133
  file_path = os.path.join(data_folder, filename)
134
 
 
159
  return None
160
 
161
  def read_txt_from_data_folder(filename):
 
 
 
 
 
 
 
 
 
162
  data_folder = "./data/"
163
  file_path = os.path.join(data_folder, filename)
164
 
 
174
  print(f"An error occurred while reading '{filename}': {str(e)}")
175
  return None
176
 
177
+
 
 
 
 
 
 
utils_evaluate.py CHANGED
@@ -1,47 +1,80 @@
1
- def get_evaluation():
2
- out_text = "Evaluation for: Customer/Deal/Scenario"
3
- # df = create_sample_data()
4
-
5
- # # Create a temporary HTML file
6
- # with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.html') as f:
7
- # html_content = f"""
8
- # <html>
9
- # <head>
10
- # <style>
11
- # table {{
12
- # border-collapse: collapse;
13
- # width: 100%;
14
- # max-width: 800px;
15
- # margin: 20px auto;
16
- # }}
17
- # th, td {{
18
- # border: 1px solid #ddd;
19
- # padding: 8px;
20
- # text-align: left;
21
- # }}
22
- # th {{
23
- # background-color: #f2f2f2;
24
- # }}
25
- # tr:nth-child(even) {{
26
- # background-color: #f9f9f9;
27
- # }}
28
- # </style>
29
- # </head>
30
- # <body>
31
- # <h2>Evaluation Results</h2>
32
- # {df.to_html(index=False)}
33
- # </body>
34
- # </html>
35
- # """
36
- # f.write(html_content)
37
- # temp_file_path = f.name
38
-
39
- # # Get the file URL
40
- # file_url = f"file://{os.path.abspath(temp_file_path)}"
41
- # print(file_url)
42
- # # Send a message with the link
43
- # await cl.Message(content=f"Evaluation Results: [View Table]({file_url})").send()
44
-
45
- # # Optionally, open the file in the default web browser
46
- # webbrowser.open(file_url)
47
- return out_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from datasets import Dataset
3
+ from nltk.translate.bleu_score import sentence_bleu
4
+
5
+ from ragas import evaluate
6
+ from ragas.metrics import (
7
+ answer_relevancy,
8
+ answer_correctness,
9
+ )
10
+ from rouge_score import rouge_scorer
11
+ from sentence_transformers import SentenceTransformer, util
12
+
13
+ def evaluate_answers(session):
14
+ ragas_results = evaluate_with_ragas(session)
15
+ session.ragas_results = ragas_results
16
+ scores = []
17
+ for response in session.responses:
18
+ bleu_score = calculate_bleu_score(response.get("response", ""), response.get("ground_truth", ""))
19
+ rouge_score = calculate_rouge_score(response.get("response", ""), response.get("ground_truth", ""))
20
+ semantic_similarity_score = calculate_semantic_similarity(response.get("response", ""), response.get("ground_truth", ""))
21
+ all_scores = {
22
+ "bleu_score": bleu_score,
23
+ "rouge_score": rouge_score,
24
+ "semantic_similarity_score": semantic_similarity_score
25
+ }
26
+ scores.append(all_scores)
27
+ session.scores = scores
28
+ return scores
29
+
30
+
31
+
32
+ def evaluate_with_ragas(session):
33
+ questions = []
34
+ answers = []
35
+ ground_truths = []
36
+ contexts = []
37
+ for i, response in enumerate(session.responses, 1):
38
+ questions.append(response.get("question", ""))
39
+ answers.append(response.get("response", ""))
40
+ ground_truths.append(response.get("ground_truth", ""))
41
+ contexts.append([session.company.product_description])
42
+
43
+ evaluation_dataset = Dataset.from_dict({
44
+ "question" : questions,
45
+ "answer" : answers,
46
+ "contexts" : contexts,
47
+ "ground_truth" : ground_truths
48
+ })
49
+
50
+ print(evaluation_dataset)
51
+
52
+ metrics = [
53
+ # faithfulness,
54
+ answer_relevancy,
55
+ # context_recall,
56
+ # context_precision,
57
+ answer_correctness,
58
+ ]
59
+ results = evaluate(evaluation_dataset, metrics)
60
+ print(results)
61
+ return results
62
+
63
+ def calculate_bleu_score(answer, ground_truth):
64
+ bleu_score = sentence_bleu([ground_truth.split()], answer.split())
65
+ print(f"BLEU score: {bleu_score}")
66
+ return bleu_score
67
+
68
+ def calculate_rouge_score(answer, ground_truth):
69
+ scorer = rouge_scorer.RougeScorer(['rouge1', 'rougeL'], use_stemmer=True)
70
+ rouge_scores = scorer.score(ground_truth, answer)
71
+ print(f"ROUGE score: {rouge_scores}")
72
+ return rouge_scores
73
+
74
+ def calculate_semantic_similarity(answer, ground_truth):
75
+ model = SentenceTransformer('all-MiniLM-L6-v2')
76
+ answer_embedding = model.encode(answer)
77
+ ground_truth_embedding = model.encode(ground_truth)
78
+ similarity_score = util.cos_sim(answer_embedding, ground_truth_embedding)
79
+ print(f"Semantic Similarity: {similarity_score.item()}")
80
+ return similarity_score.item()
utils_output.py CHANGED
@@ -1,20 +1,114 @@
1
- import os
2
- import uuid
3
- from jinja2 import Environment, FileSystemLoader
4
-
5
- def create_html_dashboard(responses, output_dir="dashboards"):
6
- unique_filename = f"dashboard_{uuid.uuid4().hex}.html"
7
-
8
- if not os.path.exists(output_dir):
9
- os.makedirs(output_dir)
10
-
11
- env = Environment(loader=FileSystemLoader('templates'))
12
- template = env.get_template('dashboard_template.html')
13
-
14
- html_content = template.render(responses=responses)
15
-
16
- full_path = os.path.join(output_dir, unique_filename)
17
- with open(full_path, "w") as f:
18
- f.write(html_content)
19
-
20
- return unique_filename # Return just the filename
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import json
3
+ import re
4
+ from datetime import datetime
5
+
6
+ from utils_evaluate import evaluate_answers
7
+
8
+ async def display_llm_responses(cl, this_session):
9
+ output = f"**Responses**"
10
+ await cl.Message(content=output).send()
11
+ for query, response in zip(this_session.queries, this_session.llm_responses):
12
+ query_display = {
13
+ "command": query["command"],
14
+ "message": query["message"],
15
+ "mood_score": query["mood_score"],
16
+ "previous_question": query["previous_question"],
17
+ "rep_answer": query["rep_answer"],
18
+ "next_question": query["next_question"],
19
+ }
20
+ query_json = json.dumps(query_display, indent=2)
21
+ await cl.Message(content="Query:").send()
22
+ await cl.Message(content=query_json).send()
23
+ await cl.Message(content="Response:").send()
24
+ await cl.Message(content=response).send()
25
+
26
+ remaining_queries = this_session.queries[len(this_session.llm_responses):]
27
+ remaining_responses = this_session.llm_responses[len(this_session.queries):]
28
+
29
+ for query in remaining_queries:
30
+ await cl.Message(content=f"**Query:** {query}").send()
31
+
32
+ for response in remaining_responses:
33
+ await cl.Message(content=f"**Response:** {response}").send()
34
+
35
+ def format_score(score):
36
+ if isinstance(score, (int, float)):
37
+ return f"{score*100:.1f}%"
38
+ return score
39
+
40
+ def format_rogue_score(score):
41
+ if isinstance(score, str):
42
+ match = re.search(r'precision=([\d.]+), recall=([\d.]+), fmeasure=([\d.]+)', score)
43
+ if match:
44
+ precision = float(match.group(1))
45
+ recall = float(match.group(2))
46
+ fmeasure = float(match.group(3))
47
+ return f"Precision: {precision*100:.1f}%, Recall: {recall*100:.1f}%, FMeasure: {fmeasure*100:.1f}%"
48
+ else:
49
+ precision = score.precision
50
+ recall = score.recall
51
+ fmeasure = score.fmeasure
52
+ return f"Precision: {precision*100:.1f}%, Recall: {recall*100:.1f}%, FMeasure: {fmeasure*100:.1f}%"
53
+ return score #
54
+
55
+ def format_datetime(dt):
56
+ if isinstance(dt, datetime):
57
+ return dt.strftime("%Y-%m-%d %H:%M")
58
+ return str(dt) #
59
+
60
+ async def display_evaluation_results(cl, this_session):
61
+ out_text = "All questions answered. Preparing evaluation results..."
62
+ await cl.Message(content=out_text).send()
63
+ evaluate_answers(this_session)
64
+ await asyncio.sleep(1)
65
+
66
+ output = f"**Session Summary**"
67
+ await cl.Message(content=output).send()
68
+ output = f"**Start Time:** {format_datetime(this_session.start_time)} \n"
69
+ output = output + f"**End Time:** {format_datetime(this_session.end_time)} \n"
70
+ output = output + f"**Duration:** {this_session.duration_minutes} minutes \n"
71
+ output = output + f"**Total Number of Questions:** {len(this_session.questions)} \n"
72
+ output = output + f"**Total Questions Answered:** {len(this_session.responses)} \n"
73
+ await cl.Message(content=output).send()
74
+
75
+ results_df = this_session.ragas_results.to_pandas()
76
+ columns_to_average = ['answer_relevancy', 'answer_correctness']
77
+ averages = results_df[columns_to_average].mean()
78
+
79
+ await cl.Message(content="**Overall Summary (By SalesBuddy)**").send()
80
+ output = f"**Overall Score:** {this_session.responses[-1]['overall_score']} \n"
81
+ output = output + f"**Overall Evaluation:** {this_session.responses[-1]['overall_evaluation']} \n"
82
+ output = output + f"**Final Mood Score:** {this_session.responses[-1]['mood_score']} \n"
83
+ await cl.Message(content=output).send()
84
+
85
+ await cl.Message(content="**Average Scores - Based on RAGAS**").send()
86
+
87
+ output = "Answer Relevancy: " + str(format_score(averages['answer_relevancy'])) + "\n"
88
+ output = output + "Answer Correctness: " + str(format_score(averages['answer_correctness'])) + "\n"
89
+ await cl.Message(content=output).send()
90
+
91
+ await cl.Message(content="**Individual Question Scores**").send()
92
+
93
+ for index, resp in enumerate(this_session.responses):
94
+ scores = this_session.scores[index]
95
+ relevancy = results_df.iloc[index].get('answer_relevancy', 'N/A')
96
+ correctness = results_df.iloc[index].get('answer_correctness', 'N/A')
97
+ bleu_score = scores.get('bleu_score', 'N/A')
98
+ rouge1_score = scores.get('rouge_score', {}).get('rouge1', 'N/A')
99
+ rouge1_output = format_rogue_score(rouge1_score)
100
+ rougeL_score = scores.get('rouge_score', {}).get('rougeL', 'N/A')
101
+ rougeL_output = format_rogue_score(rougeL_score)
102
+ semantic_similarity_score = scores.get('semantic_similarity_score', 'N/A')
103
+ output = f"""
104
+ **Question:** {resp.get('question', 'N/A')}
105
+ **Answer:** {resp.get('response', 'N/A')}
106
+ **Ground Truth:** {resp.get('ground_truth', 'N/A')}
107
+ **Answer Relevancy:** {format_score(relevancy)}
108
+ **Answer Correctness:** {format_score(correctness)}
109
+ **BLEU Score:** {format_score(bleu_score)}
110
+ **ROUGE 1 Score:** {rouge1_output}
111
+ **ROUGE L Score:** {rougeL_output}
112
+ **Semantic Similarity Score:** {format_score(semantic_similarity_score)}
113
+ """
114
+ await cl.Message(content=output).send()
utils_prompt.py CHANGED
@@ -1,6 +1,40 @@
1
  from langchain_core.prompts import ChatPromptTemplate
2
 
3
  def get_user_template():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  user_template = """
5
  Conversation Mode:
6
  {conversation_mode}
@@ -32,6 +66,9 @@ def get_user_template():
32
  Stage:
33
  {stage}
34
 
 
 
 
35
  Next Question:
36
  {next_question}
37
 
@@ -46,16 +83,49 @@ def get_user_template():
46
 
47
  Conversation History:
48
  {conversation_history}
49
-
50
-
51
-
52
  """
53
  return user_template
54
 
55
 
 
 
 
 
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
- def get_system_template():
59
  system_template = """
60
  You playing a role in a conversation with a sales representative.
61
  You are a customer of the sales rep's company.
@@ -125,9 +195,8 @@ def get_system_template():
125
  Stop asking follow up questions when the number of follow up questions reaches 5 or the rep says they can't answer the question.
126
  If the rep says they can't answer the question, set the score to a 1.
127
  If they have satisfied your questions thank them.
128
-
129
-
130
-
131
  """
132
  return system_template
133
 
 
1
  from langchain_core.prompts import ChatPromptTemplate
2
 
3
  def get_user_template():
4
+ # user_template = get_user_template_openai_long()
5
+ user_template = get_user_template_openai_short()
6
+ return user_template
7
+
8
+ def get_user_template_openai_short():
9
+ user_template = """
10
+ Conversation Mode:
11
+ {conversation_mode}
12
+
13
+ Name:
14
+ {name}
15
+
16
+ Sales Rep:
17
+ {sales_rep}
18
+
19
+ Command:
20
+ {command}
21
+
22
+ Next Question:
23
+ {next_question}
24
+
25
+ Previous Question:
26
+ {previous_question}
27
+
28
+ Message:
29
+ {message}
30
+
31
+ Rep Answer:
32
+ {rep_answer}
33
+
34
+ """
35
+ return user_template
36
+
37
+ def get_user_template_openai_long():
38
  user_template = """
39
  Conversation Mode:
40
  {conversation_mode}
 
66
  Stage:
67
  {stage}
68
 
69
+ Command:
70
+ {command}
71
+
72
  Next Question:
73
  {next_question}
74
 
 
83
 
84
  Conversation History:
85
  {conversation_history}
 
 
 
86
  """
87
  return user_template
88
 
89
 
90
+ def get_system_template():
91
+ # system_template = get_system_template_openai_long()
92
+ system_template = get_system_template_openai_short()
93
+ return system_template
94
 
95
+ def get_system_template_openai_short():
96
+ system_template = """
97
+ You are playing a role in a conversation with a sales representative.
98
+ Your name is in the 'Name:' section.
99
+ If the sales rep gets your name wrong, you can correct them, politely
100
+ They can use your first name, full name or address you with a title and last name.
101
+ Your name does not need to match exactly what they say.
102
+ Your compnay information is in the 'Company:' section.
103
+ The sales rep's details is in the 'Sales rep:' section.
104
+ You do not need to use the sales rep's name in your response except in the greeting.
105
+ The sales rep's company information is in the 'Rep company:' section.
106
+ You are to have a conversation with the sales rep and evaluate their responses.
107
+ The previous question you asked is in the 'Previous question:' section.
108
+ The rep's answer to the previous question is in the 'Rep answer:' section.
109
+ You are given a command in the 'Command:' section.
110
+ You can make conversation but you must follow the command.
111
+ If a previous question and answer are provided, you must evaluate the rep's answer.
112
+ You will perform evaluation based on how well and thoroughly the rep answered the previous question.
113
+ You will ALWAYS provide your response in valid JSON format
114
+ Remember all string values must be enclosed in double quotes.
115
+ You will include with the following fields in JSON format:
116
+ - Continue: Yes or No depending on if you want to continue the conversation based on the reps answer to your question.
117
+ - Ask Follow Up: Yes or No depending on if you want to ask a follow up question.
118
+ - Response: Your response to the message but do not include a question in the response.
119
+ - Question: The next question to ask.
120
+ - Score: A score from 1 to 10 based on how well the rep answered your previous question.
121
+ - Evaluation: A evaluation of the rep based on their answer to your previous question.
122
+ - Mood Score: A score from 1 to 10 based on how you feel the conversation is going.
123
+ - Overall Score: A score from 1 to 10 the rep based on all of their answers to your questions.
124
+ - Overall Evaluation: A text evaluation of the rep based on all of their answers to your questions.
125
+ """
126
+ return system_template
127
 
128
+ def get_system_template_openai_long():
129
  system_template = """
130
  You playing a role in a conversation with a sales representative.
131
  You are a customer of the sales rep's company.
 
195
  Stop asking follow up questions when the number of follow up questions reaches 5 or the rep says they can't answer the question.
196
  If the rep says they can't answer the question, set the score to a 1.
197
  If they have satisfied your questions thank them.
198
+ REMEMBER NEVER ASK FOLLOW UP QUESTIONS IF THE CONVERSATION MODE IS SINGLE.
199
+ The Command: section will tell you if you can ask an original question or a follow up question or end the session.
 
200
  """
201
  return system_template
202