BMCVRN commited on
Commit
16d7236
·
verified ·
1 Parent(s): 28f9ad7

Persona Integration & Modified User Context (#12)

Browse files

- Persona Integration and Slight change to context management (f48f0e5418a56a3ab910f9b721fffb25d9a1b4db)
- Aligned with staging (06a04bf9b4ba7516248d9bc0d63bfa9760d345fd)
- Persona Integration with Intro Assistant (ba89b7ca010122cd06cde9ae38ba5c2174bfb584)
- Post GG intergration with FINAL_SUMMARY_STATE (9d67a76696536365ad9027cc33460bbf40c8849b)

app/__pycache__/assistants.cpython-312.pyc CHANGED
Binary files a/app/__pycache__/assistants.cpython-312.pyc and b/app/__pycache__/assistants.cpython-312.pyc differ
 
app/__pycache__/flows.cpython-312.pyc CHANGED
Binary files a/app/__pycache__/flows.cpython-312.pyc and b/app/__pycache__/flows.cpython-312.pyc differ
 
app/__pycache__/main.cpython-312.pyc CHANGED
Binary files a/app/__pycache__/main.cpython-312.pyc and b/app/__pycache__/main.cpython-312.pyc differ
 
app/__pycache__/user.cpython-312.pyc CHANGED
Binary files a/app/__pycache__/user.cpython-312.pyc and b/app/__pycache__/user.cpython-312.pyc differ
 
app/__pycache__/utils.cpython-312.pyc CHANGED
Binary files a/app/__pycache__/utils.cpython-312.pyc and b/app/__pycache__/utils.cpython-312.pyc differ
 
app/assistants.py CHANGED
@@ -382,7 +382,7 @@ class Assistant:
382
  return run, just_finished_intro, message
383
 
384
  elif run.status == 'failed':
385
- raise OpenAIRequestError(user_id=self.cm.user.id, message="Run failed", run_id=run.id)
386
 
387
  elif run.status == 'requires_action':
388
  reccursion = 0
 
382
  return run, just_finished_intro, message
383
 
384
  elif run.status == 'failed':
385
+ raise OpenAIRequestError(user_id=self.cm.user.user_id, message="Run failed", run_id=run.id)
386
 
387
  elif run.status == 'requires_action':
388
  reccursion = 0
app/conversation_manager.py CHANGED
@@ -9,8 +9,12 @@ from app.exceptions import BaseOurcoachException, ConversationManagerError, Open
9
  from datetime import datetime
10
 
11
  import dotenv
 
 
12
  dotenv.load_dotenv()
13
 
 
 
14
  logger = logging.getLogger(__name__)
15
 
16
  def get_current_datetime():
@@ -62,12 +66,17 @@ class ConversationManager:
62
  thread = self.client.beta.threads.create()
63
  self.system_message = self.add_message_to_thread(thread.id, "assistant",
64
  f"""
 
 
 
 
65
  You are coaching:
66
  \n\n{user_interaction_guidelines}\n\n\
67
  Be mindful of this information at all times in order to
68
  be as personalised as possible when conversing. Ensure to
69
  follow the conversation guidelines and flow templates. Use the
70
  current state of the conversation to adhere to the flow. Do not let the user know about any transitions.\n\n
 
71
  ** Today is {self.state['date']}.\n\n **
72
  ** You are now in the INTRODUCTION STATE. **
73
  """)
@@ -185,7 +194,7 @@ class ConversationManager:
185
  # OPENAI LIMITATION: Can only attach a maximum of 32 messages when creating a new thread
186
  messages = self._get_current_thread_history(remove_system_message=False)
187
  if len(messages) >= 29:
188
- messages = [{"content": """ Remember who you are coaching.
189
  Be mindful of this information at all times in order to
190
  be as personalised as possible when conversing. Ensure to
191
  follow the conversation guidelines and flow provided.""", "role":"assistant"}] + messages[-29:]
 
9
  from datetime import datetime
10
 
11
  import dotenv
12
+
13
+ from app.utils import id_to_persona
14
  dotenv.load_dotenv()
15
 
16
+ OURCOACH_DASHBOARD_URL = os.getenv("OURCOACH_DASHBOARD_URL")
17
+
18
  logger = logging.getLogger(__name__)
19
 
20
  def get_current_datetime():
 
66
  thread = self.client.beta.threads.create()
67
  self.system_message = self.add_message_to_thread(thread.id, "assistant",
68
  f"""
69
+ You are:
70
+ {id_to_persona(self.user.asst_id)}, always adhere to your choosen persona by incorporating it conversationally.
71
+ You represent a coach at ourcoach. You may refer to you knowledgebase for all information related to ourcoach.
72
+ -------------------------------------------
73
  You are coaching:
74
  \n\n{user_interaction_guidelines}\n\n\
75
  Be mindful of this information at all times in order to
76
  be as personalised as possible when conversing. Ensure to
77
  follow the conversation guidelines and flow templates. Use the
78
  current state of the conversation to adhere to the flow. Do not let the user know about any transitions.\n\n
79
+ Whenever you reference the dashboard or Revelation Dashboard, inlcue the link: {OURCOACH_DASHBOARD_URL} .
80
  ** Today is {self.state['date']}.\n\n **
81
  ** You are now in the INTRODUCTION STATE. **
82
  """)
 
194
  # OPENAI LIMITATION: Can only attach a maximum of 32 messages when creating a new thread
195
  messages = self._get_current_thread_history(remove_system_message=False)
196
  if len(messages) >= 29:
197
+ messages = [{"content": """ Remember who you are and who you are coaching.
198
  Be mindful of this information at all times in order to
199
  be as personalised as possible when conversing. Ensure to
200
  follow the conversation guidelines and flow provided.""", "role":"assistant"}] + messages[-29:]
app/flows.py CHANGED
@@ -483,11 +483,14 @@ Objective: To summarize the user's progress and achievements during the coaching
483
  Users Goal: {{}}
484
  The user is currently on day {{}}/{{}} of their journey.
485
 
 
 
 
486
  ## ** GUIDELINE ** :
487
 
488
  ## What Makes a Good Interaction:
489
 
490
- - Highlight the user's progress and achievements precisely and concisely. Use bullet points to list down your items.
491
 
492
  - Explain to the user that coaching is a continuous journey, so the user has the option to either continue with the same goal or create a new plan.
493
 
@@ -505,13 +508,14 @@ The user is currently on day {{}}/{{}} of their journey.
505
 
506
  - Congratulate the user for completing the growth plan until the last day (mention the current day, e.g. day 4)
507
 
508
- - Highlight the user's progress and achievements in bullet points. And tell them to check out their progress in the Revelation Dashboard here: https://app.staging.ourcoach.ai/
509
-
510
- - Ask the user whether they want to meet their Growth Guide to plan what's next! (Only ask this question first)
511
 
 
 
 
512
  - Wait for the user's response.
513
 
514
- - **IF** the user answer with a Yes, you reply with this message:
515
 
516
  Amazing! 🎉
517
 
 
483
  Users Goal: {{}}
484
  The user is currently on day {{}}/{{}} of their journey.
485
 
486
+ User's Last Growth Guide Session:
487
+ {{}}
488
+
489
  ## ** GUIDELINE ** :
490
 
491
  ## What Makes a Good Interaction:
492
 
493
+ - Highlight the user's progress and achievements precisely and concisely. IF the user has completed a growth guide session (see above), incorporate it into your response and reference that it was acheived during their growth guide session. Use bullet points to list down your items.
494
 
495
  - Explain to the user that coaching is a continuous journey, so the user has the option to either continue with the same goal or create a new plan.
496
 
 
508
 
509
  - Congratulate the user for completing the growth plan until the last day (mention the current day, e.g. day 4)
510
 
511
+ - Highlight the user's progress and achievements in bullet points. IF the user has completed a growth guide session (see above), incorporate it into your response and reference that it was acheived during their growth guide session. And tell them to check out their progress in the Revelation Dashboard here: https://app.staging.ourcoach.ai/
 
 
512
 
513
+ - IF the user has not completed a growth guide session yet (see above), encourage the user to book a Growth Guide session and explain its benefits. Really upsell this by being like a Growth Guide salesman!
514
+ - ELSE IF the user has booked a growth guide session (see above), tell them you hope it went well and they found it beneficial and let the use know that they could also book another via their Revelation Dashboard: https://app.staging.ourcoach.ai/
515
+
516
  - Wait for the user's response.
517
 
518
+ - **IF** the user says they want to book a growth guide session, you reply with this message:
519
 
520
  Amazing! 🎉
521
 
app/main.py CHANGED
@@ -257,8 +257,6 @@ class LoggingMiddleware(BaseHTTPMiddleware):
257
  raise
258
 
259
  # OpenAI Client
260
- # GENERAL_ASSISTANT = os.getenv('OPENAI_GENERAL_ASSISTANT')
261
- GENERAL_ASSISTANT = "asst_vnucWWELJlCWadfAARwyKkCW"
262
 
263
  # Initialize Logging (optional)
264
  # logging.basicConfig(filename='app.log', level=logging.INFO)
@@ -485,7 +483,7 @@ async def migrate_user(
485
 
486
  with open(user_file, 'rb') as f:
487
  old_user_object = pickle.load(f)
488
- user = User(request.user_id, old_user_object.user_info, client, GENERAL_ASSISTANT)
489
  user.conversations.current_thread = old_user_object.conversations.current_thread
490
  user.conversations.intro_done = True
491
  user.done_first_reflection = old_user_object.done_first_reflection
@@ -741,8 +739,29 @@ async def create_user(
741
  if os.path.exists(f'users/data/{request.user_id}.pkl'):
742
  return {"message": f"[OK] User already exists: {request.user_id}"}
743
 
744
- user_info, _ = get_user_info(request.user_id)
745
- user = User(request.user_id, user_info, client, GENERAL_ASSISTANT)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
746
  folder_path = os.path.join("mementos", "to_upload", request.user_id)
747
  os.makedirs(folder_path, exist_ok=True)
748
 
@@ -899,7 +918,10 @@ async def get_summary_by_id(
899
  ):
900
  print_log("INFO", "Getting user's summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
901
  logger.info("Getting user's summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
902
- user_summary = get_user_summary(user_id)
 
 
 
903
  print_log("INFO", "Successfully generated summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
904
  logger.info("Successfully generated summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
905
  return user_summary
 
257
  raise
258
 
259
  # OpenAI Client
 
 
260
 
261
  # Initialize Logging (optional)
262
  # logging.basicConfig(filename='app.log', level=logging.INFO)
 
483
 
484
  with open(user_file, 'rb') as f:
485
  old_user_object = pickle.load(f)
486
+ user = User(request.user_id, old_user_object.user_info, client, old_user_object.asst_id)
487
  user.conversations.current_thread = old_user_object.conversations.current_thread
488
  user.conversations.intro_done = True
489
  user.done_first_reflection = old_user_object.done_first_reflection
 
739
  if os.path.exists(f'users/data/{request.user_id}.pkl'):
740
  return {"message": f"[OK] User already exists: {request.user_id}"}
741
 
742
+ user_info, persona = get_user_info(request.user_id)
743
+ # Persona is one of ["Coach Steve", "Coach Aris", "Coach Teresa"]
744
+ # we map each of the above to assistant_ids = ["asst_mUm6MBcW544p1iVov9mwIC96", "asst_4WcktKgYdDnXA1QUlWvrNfWV", "asst_4UVkFK6r2pbz6NK6kNzG4sTW"]
745
+ persona_to_assistant = {
746
+ "Coach Steve": "asst_mUm6MBcW544p1iVov9mwIC96",
747
+ "Coach Aris": "asst_4WcktKgYdDnXA1QUlWvrNfWV",
748
+ "Coach Teresa": "asst_4UVkFK6r2pbz6NK6kNzG4sTW"
749
+ }
750
+
751
+ if persona not in persona_to_assistant:
752
+ logger.warning(f"Invalid persona: {persona}, defaulting to: Coach Steve", extra={"user_id": request.user_id, "endpoint": "/create_user"})
753
+ # For testing we default to steve
754
+ persona = "Coach Steve"
755
+ # raise FastAPIError(
756
+ # message="Invalid persona",
757
+ # e="Persona must be one of ['Coach Steve', 'Coach Aris', 'Coach Teresa']"
758
+ # )
759
+
760
+ selected_persona = persona_to_assistant[persona]
761
+
762
+ logger.info(f"Creating user with persona {persona}:{selected_persona}", extra={"user_id": request.user_id, "endpoint": "/create_user"})
763
+
764
+ user = User(request.user_id, user_info, client, selected_persona)
765
  folder_path = os.path.join("mementos", "to_upload", request.user_id)
766
  os.makedirs(folder_path, exist_ok=True)
767
 
 
918
  ):
919
  print_log("INFO", "Getting user's summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
920
  logger.info("Getting user's summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
921
+
922
+ # NOTE: This call will also update the users recommended topics to discuss with GG.
923
+ # This is so that the AI response will align with the dashboard.
924
+ user_summary = get_user_summary(user_id, update_rec_topics=True)
925
  print_log("INFO", "Successfully generated summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
926
  logger.info("Successfully generated summary", extra={"user_id": user_id, "endpoint": "/get_user_summary"})
927
  return user_summary
app/user.py CHANGED
@@ -19,7 +19,7 @@ from app.flows import FINAL_SUMMARY_STATE, FINAL_SUMMARY_STATE, MICRO_ACTION_STA
19
  from pydantic import BaseModel
20
  from datetime import datetime
21
 
22
- from app.utils import generate_uuid, update_growth_guide_summary
23
 
24
  import dotenv
25
  import re
@@ -97,7 +97,7 @@ class User:
97
  },
98
  {
99
  "day": 3,
100
- "coachingTheme": "OPEN_DISCUSSION_STATE"
101
  },
102
  {
103
  "day": 4,
@@ -107,8 +107,7 @@ class User:
107
  "day": 5,
108
  "coachingTheme": "FINAL_SUMMARY_STATE"
109
  }
110
- ]
111
- }
112
 
113
 
114
  self.growth_plan = CircularQueue(array=growth_plan['growthPlan'], user_id=self.user_id)
@@ -191,7 +190,7 @@ class User:
191
  def add_recent_wins(self, wins, context = None):
192
  prompt = f"""
193
  ## Role
194
- You are an expert in writing achievement message and progress notification. Your task is to use the user's achievement and context to formulate a short and creative achievement message/progress notification. The output must be a one sentence short message (less than 15 words) in this JSON output schema:
195
 
196
  ```json
197
  {{
@@ -208,7 +207,7 @@ class User:
208
  Output:
209
  ```
210
  {{
211
- achievement_message: You crushed it! Completing that 10k run is a huge milestone—way to go!
212
  }}
213
  ```
214
 
@@ -640,7 +639,10 @@ class User:
640
  elif theme == "PROGRESS_SUMMARY_STATE":
641
  formatted_message = PROGRESS_SUMMARY_STATE.format(self.get_current_goal(), day, len(self.growth_plan.array))
642
  elif theme == "FINAL_SUMMARY_STATE":
643
- formatted_message = FINAL_SUMMARY_STATE.format(self.get_current_goal(), day, len(self.growth_plan.array))
 
 
 
644
  elif theme == "EDUCATION_STATE":
645
  formatted_message = EDUCATION_STATE.format(self.get_current_goal(), day, len(self.growth_plan.array))
646
  elif theme == "FOLLUP_ACTION_STATE":
@@ -702,6 +704,8 @@ class User:
702
 
703
  8. You **MUST** call the process_reminder() function if the user wants to postpone their micro-action
704
 
 
 
705
  Today's Theme:
706
  {formatted_message}
707
  """
@@ -804,7 +808,7 @@ class User:
804
  logger.info(f"Summarizing zoom ai summary", extra={"user_id": self.user_id, "endpoint": "summarize_zoom"})
805
  # make an api call to gpt4o to summarize the zoom_ai_summary and produce a text with a focus on the most amount of user insight and info extracted
806
  system_prompt = f"""You are an expert at summarizing AI-generated Zoom transcripts concisely, focusing on extracting key user insights to enhance personalization in future interactions. Note that the zoom ai transcript may get the user's name wrong. Replace it with the actual user's name: {self.user_info}. Refer to the coach/guide as 'the Growth Guide'."""
807
- prompt = f"Please summarize the following AI-generated Zoom transcript **in one short paragraph only** !!, emphasizing the most significant user insights and information:\n\n{zoom_ai_summary}"
808
 
809
  response = self.client.chat.completions.create(
810
  model="gpt-4o",
@@ -812,10 +816,32 @@ class User:
812
  {"role": "system", "content": system_prompt},
813
  {"role": "user", "content": prompt}
814
  ],
815
- temperature=0.2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
816
  )
817
- logger.info(f"Summary: {response.choices[0].message.content}", extra={"user_id": self.user_id, "endpoint": "summarize_zoom"})
818
- return {'overview': response.choices[0].message.content}
 
 
819
 
820
  @catch_error
821
  def _update_user_data(self, data_type, text_input, extra_text=""):
@@ -1006,12 +1032,15 @@ class User:
1006
  if completed_micro_action:
1007
  self.micro_actions[-1].status = "COMPLETE"
1008
  self.micro_actions[-1].updated_at = pd.Timestamp.now(tz='UTC').strftime("%d-%m-%Y %a %H:%M:%S")
 
1009
 
1010
  num_of_micro_actions_completed = sum(1 for item in self.micro_actions if item.status == 'COMPLETE')
1011
 
1012
  if (num_of_micro_actions_completed in (1,3,5)) or (num_of_micro_actions_completed % 10 == 0 and num_of_micro_actions_completed != 0):
1013
  self.add_life_score_point(variable = self.get_current_goal(full=True).area, points_added = 10, notes = f"Completing the {num_of_micro_actions_completed}-th micro-action")
1014
- self.add_recent_wins(wins = "You have completed a micro action!", context= self.micro_actions[-1]['content'])
 
 
1015
 
1016
  @catch_error
1017
  def trigger_deep_reflection_point(self, area_of_deep_reflection):
 
19
  from pydantic import BaseModel
20
  from datetime import datetime
21
 
22
+ from app.utils import generate_uuid, get_growth_guide_summary, update_growth_guide_summary
23
 
24
  import dotenv
25
  import re
 
97
  },
98
  {
99
  "day": 3,
100
+ "coachingTheme": "FINAL_SUMMARY_STATE"
101
  },
102
  {
103
  "day": 4,
 
107
  "day": 5,
108
  "coachingTheme": "FINAL_SUMMARY_STATE"
109
  }
110
+ ]}
 
111
 
112
 
113
  self.growth_plan = CircularQueue(array=growth_plan['growthPlan'], user_id=self.user_id)
 
190
  def add_recent_wins(self, wins, context = None):
191
  prompt = f"""
192
  ## Role
193
+ You are an expert in writing achievement message and progress notification. Your task is to use the user's achievement and context to formulate a short achievement message/progress notification. The output must be a one sentence short message (less than 15 words) in this JSON output schema:
194
 
195
  ```json
196
  {{
 
207
  Output:
208
  ```
209
  {{
210
+ achievement_message: You have completed a 10k run!
211
  }}
212
  ```
213
 
 
639
  elif theme == "PROGRESS_SUMMARY_STATE":
640
  formatted_message = PROGRESS_SUMMARY_STATE.format(self.get_current_goal(), day, len(self.growth_plan.array))
641
  elif theme == "FINAL_SUMMARY_STATE":
642
+ gg_summary = "<User has not had a Growth Guide session yet>"
643
+ if self.last_gg_session:
644
+ gg_summary = get_growth_guide_summary(self.user_id, self.last_gg_session)
645
+ formatted_message = FINAL_SUMMARY_STATE.format(self.get_current_goal(), day, len(self.growth_plan.array), gg_summary)
646
  elif theme == "EDUCATION_STATE":
647
  formatted_message = EDUCATION_STATE.format(self.get_current_goal(), day, len(self.growth_plan.array))
648
  elif theme == "FOLLUP_ACTION_STATE":
 
704
 
705
  8. You **MUST** call the process_reminder() function if the user wants to postpone their micro-action
706
 
707
+ 9. When talking about Growth Guide, you must try to upsell the growth guide. Meaning that you are always encouraging the user to book a Growth Guide session and explain it benefits. Be like the Growth Guide's salesman!
708
+
709
  Today's Theme:
710
  {formatted_message}
711
  """
 
808
  logger.info(f"Summarizing zoom ai summary", extra={"user_id": self.user_id, "endpoint": "summarize_zoom"})
809
  # make an api call to gpt4o to summarize the zoom_ai_summary and produce a text with a focus on the most amount of user insight and info extracted
810
  system_prompt = f"""You are an expert at summarizing AI-generated Zoom transcripts concisely, focusing on extracting key user insights to enhance personalization in future interactions. Note that the zoom ai transcript may get the user's name wrong. Replace it with the actual user's name: {self.user_info}. Refer to the coach/guide as 'the Growth Guide'."""
811
+ prompt = f"Please summarize the following AI-generated Zoom transcript **in one short paragraph only, around 50 completion tokens maximum** !!, emphasizing the most significant user insights and information:\n\n{zoom_ai_summary}"
812
 
813
  response = self.client.chat.completions.create(
814
  model="gpt-4o",
 
816
  {"role": "system", "content": system_prompt},
817
  {"role": "user", "content": prompt}
818
  ],
819
+ response_format = {
820
+ "type": "json_schema",
821
+ "json_schema": {
822
+ "name": "summarized_overview",
823
+ "strict": True,
824
+ "schema": {
825
+ "type": "object",
826
+ "properties": {
827
+ "summary": {
828
+ "type": "string",
829
+ "description": "The summary of the zoom transcript"
830
+ }
831
+ },
832
+ "required": [
833
+ "summary"
834
+ ],
835
+ "additionalProperties": False
836
+ }
837
+ }
838
+ },
839
+ temperature=0.5
840
  )
841
+
842
+ overview_summary = json.loads(response.choices[0].message.content)['summary']
843
+ logger.info(f"Summary: {overview_summary}", extra={"user_id": self.user_id, "endpoint": "summarize_zoom"})
844
+ return {'overview': overview_summary}
845
 
846
  @catch_error
847
  def _update_user_data(self, data_type, text_input, extra_text=""):
 
1032
  if completed_micro_action:
1033
  self.micro_actions[-1].status = "COMPLETE"
1034
  self.micro_actions[-1].updated_at = pd.Timestamp.now(tz='UTC').strftime("%d-%m-%Y %a %H:%M:%S")
1035
+ logger.info("Micro action status updated, checking number of actions completed...", extra={"user_id": self.user_id, "endpoint": "update_micro_action_status"})
1036
 
1037
  num_of_micro_actions_completed = sum(1 for item in self.micro_actions if item.status == 'COMPLETE')
1038
 
1039
  if (num_of_micro_actions_completed in (1,3,5)) or (num_of_micro_actions_completed % 10 == 0 and num_of_micro_actions_completed != 0):
1040
  self.add_life_score_point(variable = self.get_current_goal(full=True).area, points_added = 10, notes = f"Completing the {num_of_micro_actions_completed}-th micro-action")
1041
+ self.add_recent_wins(wins = "You have completed a micro action!", context= self.micro_actions[-1].content)
1042
+ logger.info("Added life score points based on number of actions completed.", extra={"user_id": self.user_id, "endpoint": "update_micro_action_status"})
1043
+ logger.info("Process done.", extra={"user_id": self.user_id, "endpoint": "update_micro_action_status"})
1044
 
1045
  @catch_error
1046
  def trigger_deep_reflection_point(self, area_of_deep_reflection):
app/utils.py CHANGED
@@ -1,14 +1,13 @@
1
  import logging
2
  import boto3
3
- from botocore.exceptions import ClientError, NoCredentialsError, PartialCredentialsError
4
  import os
5
  from dotenv import load_dotenv
6
- from fastapi import FastAPI, HTTPException, Security, Query, status
7
  from fastapi.security import APIKeyHeader
8
  from openai import OpenAI
9
  import openai
10
  import pandas as pd
11
- from pydantic import BaseModel
12
  import os
13
  import logging
14
  import json
@@ -17,17 +16,11 @@ from psycopg2 import sql
17
  import os
18
  from dotenv import load_dotenv
19
  from datetime import datetime, timezone
20
- import threading
21
  import pickle # Replace dill with pickle
22
- from cachetools import TTLCache
23
- import threading
24
- import time
25
  import uuid
26
  from app.cache import CustomTTLCache, upload_file_to_s3
27
  import pdfkit
28
  import PyPDF2
29
- import secrets
30
- import string
31
 
32
  from app.exceptions import BaseOurcoachException, DBError, OpenAIRequestError, UtilsError
33
 
@@ -346,7 +339,7 @@ def generate_html(json_data, coach_name='Growth Guide', booking_id = None):
346
  raise DBError(user_id="no-user", message="Error uploading file to S3", code="S3Error")
347
 
348
  @catch_error
349
- def get_user_summary(user_id):
350
  function_name = get_user_summary.__name__
351
  logger.info(f"Generating user summary for user {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
352
 
@@ -829,7 +822,8 @@ def get_user_summary(user_id):
829
  # reports['html_report'] = html_output
830
 
831
  # Store users_growth_guide_preparation_brief in the User object
832
- user.set_recommened_gg_topics(reports['users_growth_guide_preparation_brief'])
 
833
 
834
  # Step 4: Return the JSON reports
835
  logger.info(f"User summary generated successfully for user {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
@@ -1107,7 +1101,6 @@ def get_user_info(user_id):
1107
  {user_data_clean.get('firstName', '')}'s challenges (You **must** use this information for the PLANNING STATE):
1108
  {challenges}
1109
 
1110
- {user_data_clean.get('firstName', '')}'s Legendary Persona: {user_data_clean.get('legendPersona', '')}
1111
  Pronouns: {user_data_clean.get('pronouns', '')}
1112
  Birthday: {user_data_clean.get('birthDate', '')}
1113
  {user_data_clean.get('firstName', '')}'s MBTI: {user_data_clean.get('mbti', '')}
@@ -1126,7 +1119,7 @@ def get_user_info(user_id):
1126
  {whoImportant}
1127
  """
1128
  logger.info(f"User info retrieved successfully for {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
1129
- return user_data_formatted, user_data_clean.get('mattersMost', ['', '', '', '', ''])
1130
  else:
1131
  logger.warning(f"No user info found for {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
1132
  raise DBError(user_id=user_id, message="Error retrieving user info", code="NoOnboardingError", e=str(e))
@@ -1466,6 +1459,22 @@ def get_users_mementos(user_id, date):
1466
  finally:
1467
  return mementos
1468
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1469
  @catch_error
1470
  def get_user_subscriptions(user_id):
1471
  function_name = get_user_subscriptions.__name__
 
1
  import logging
2
  import boto3
3
+ from botocore.exceptions import NoCredentialsError, PartialCredentialsError
4
  import os
5
  from dotenv import load_dotenv
6
+ from fastapi import HTTPException, Security, Query, status
7
  from fastapi.security import APIKeyHeader
8
  from openai import OpenAI
9
  import openai
10
  import pandas as pd
 
11
  import os
12
  import logging
13
  import json
 
16
  import os
17
  from dotenv import load_dotenv
18
  from datetime import datetime, timezone
 
19
  import pickle # Replace dill with pickle
 
 
 
20
  import uuid
21
  from app.cache import CustomTTLCache, upload_file_to_s3
22
  import pdfkit
23
  import PyPDF2
 
 
24
 
25
  from app.exceptions import BaseOurcoachException, DBError, OpenAIRequestError, UtilsError
26
 
 
339
  raise DBError(user_id="no-user", message="Error uploading file to S3", code="S3Error")
340
 
341
  @catch_error
342
+ def get_user_summary(user_id, update_rec_topics=False):
343
  function_name = get_user_summary.__name__
344
  logger.info(f"Generating user summary for user {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
345
 
 
822
  # reports['html_report'] = html_output
823
 
824
  # Store users_growth_guide_preparation_brief in the User object
825
+ if update_rec_topics:
826
+ user.set_recommened_gg_topics(reports['users_growth_guide_preparation_brief'])
827
 
828
  # Step 4: Return the JSON reports
829
  logger.info(f"User summary generated successfully for user {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
 
1101
  {user_data_clean.get('firstName', '')}'s challenges (You **must** use this information for the PLANNING STATE):
1102
  {challenges}
1103
 
 
1104
  Pronouns: {user_data_clean.get('pronouns', '')}
1105
  Birthday: {user_data_clean.get('birthDate', '')}
1106
  {user_data_clean.get('firstName', '')}'s MBTI: {user_data_clean.get('mbti', '')}
 
1119
  {whoImportant}
1120
  """
1121
  logger.info(f"User info retrieved successfully for {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
1122
+ return user_data_formatted, user_data_clean.get('legendPersona', '')
1123
  else:
1124
  logger.warning(f"No user info found for {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
1125
  raise DBError(user_id=user_id, message="Error retrieving user info", code="NoOnboardingError", e=str(e))
 
1459
  finally:
1460
  return mementos
1461
 
1462
+ @catch_error
1463
+ def id_to_persona(assistant_id):
1464
+ # persona_to_assistant = {
1465
+ # "Coach Steve": "asst_mUm6MBcW544p1iVov9mwIC96",
1466
+ # "Coach Aris": "asst_4WcktKgYdDnXA1QUlWvrNfWV",
1467
+ # "Coach Teresa": "asst_4UVkFK6r2pbz6NK6kNzG4sTW"
1468
+ # }
1469
+
1470
+ assistant_to_persona = {
1471
+ "asst_mUm6MBcW544p1iVov9mwIC96": "Coach Steve, based on the persona of Steve Jobs",
1472
+ "asst_4WcktKgYdDnXA1QUlWvrNfWV": "Coach Aris, based on the persona of Aristotle",
1473
+ "asst_4UVkFK6r2pbz6NK6kNzG4sTW": "Coach Teresa, based on the persona of Mother Teresa"
1474
+ }
1475
+
1476
+ return assistant_to_persona.get(assistant_id, "Coach Steve, based on the persona of Steve Jobs")
1477
+
1478
  @catch_error
1479
  def get_user_subscriptions(user_id):
1480
  function_name = get_user_subscriptions.__name__