Spaces:
Sleeping
Sleeping
Shageenderan Sapai commited on
Commit ·
37742a6
1
Parent(s): 15aadee
Added comprehensive logging
Browse files- app/__pycache__/assistants.cpython-312.pyc +0 -0
- app/__pycache__/main.cpython-312.pyc +0 -0
- app/__pycache__/user.cpython-312.pyc +0 -0
- app/__pycache__/utils.cpython-312.pyc +0 -0
- app/assistants.py +30 -28
- app/logs/app.log +175 -0
- app/logs/users/55ff3647-1694-4e78-a93a-091f3e099ced.log +231 -0
- app/logs/users/no-user.log +4 -0
- app/main.py +238 -21
- app/user.py +30 -22
- app/utils.py +46 -11
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__/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
|
@@ -6,9 +6,12 @@ import json
|
|
| 6 |
import random
|
| 7 |
import pandas as pd
|
| 8 |
from dotenv import load_dotenv
|
|
|
|
| 9 |
|
| 10 |
load_dotenv()
|
| 11 |
|
|
|
|
|
|
|
| 12 |
import requests
|
| 13 |
|
| 14 |
class SearchEngine:
|
|
@@ -303,13 +306,14 @@ class Assistant:
|
|
| 303 |
thread_id=thread.id,
|
| 304 |
)
|
| 305 |
else:
|
| 306 |
-
|
| 307 |
return run
|
| 308 |
|
| 309 |
def call_tool(self, run, thread):
|
| 310 |
tool_outputs = []
|
| 311 |
-
|
| 312 |
-
|
|
|
|
| 313 |
for tool in run.required_action.submit_tool_outputs.tool_calls:
|
| 314 |
if tool.function.name == "generate_coaching_plan":
|
| 315 |
user_challenge = json.loads(tool.function.arguments)
|
|
@@ -319,7 +323,8 @@ class Assistant:
|
|
| 319 |
})
|
| 320 |
elif tool.function.name == "transition":
|
| 321 |
transitions = json.loads(tool.function.arguments)
|
| 322 |
-
|
|
|
|
| 323 |
|
| 324 |
if transitions['to'] == "REFLECTION STATE":
|
| 325 |
self.cm.user.matters_most.next()
|
|
@@ -335,7 +340,8 @@ class Assistant:
|
|
| 335 |
current_time = get_current_datetime()
|
| 336 |
# replace time component of self.cm.state['date'] with the current time
|
| 337 |
self.cm.state['date'] = str(pd.to_datetime(self.cm.state['date']).replace(hour=current_time.hour, minute=current_time.minute, second=current_time.second))
|
| 338 |
-
|
|
|
|
| 339 |
|
| 340 |
tool_outputs.append({
|
| 341 |
"tool_call_id": tool.id,
|
|
@@ -345,7 +351,8 @@ class Assistant:
|
|
| 345 |
json_string = json.loads(tool.function.arguments)
|
| 346 |
json_string['created'] = str(self.cm.state['date'])
|
| 347 |
json_string['updated'] = None
|
| 348 |
-
|
|
|
|
| 349 |
|
| 350 |
# Create a folder for the user's mementos if it doesn't exist
|
| 351 |
user_mementos_folder = os.path.join("mementos", "to_upload", self.cm.user.user_id)
|
|
@@ -357,20 +364,8 @@ class Assistant:
|
|
| 357 |
file_path = os.path.join(user_mementos_folder, f"{json_string['title']}.json")
|
| 358 |
|
| 359 |
# Save the JSON string as a file
|
| 360 |
-
with open(file_path, "
|
| 361 |
json.dump(json_string, json_file)
|
| 362 |
-
|
| 363 |
-
# # Add the event to the user's vector store
|
| 364 |
-
# # get or create vector store 'events'
|
| 365 |
-
# memory_file = self.cm.client.files.create(file=open(f"mementos/{self.cm.user.user_id}/{json_string['title']}.json", "rb"),\
|
| 366 |
-
# purpose="assistants")
|
| 367 |
-
|
| 368 |
-
# vector_store_file = self.cm.client.beta.vector_stores.files.create(
|
| 369 |
-
# vector_store_id=self.cm.user_personal_memory.id,
|
| 370 |
-
# file_id=memory_file.id
|
| 371 |
-
# )
|
| 372 |
-
|
| 373 |
-
# print(f"[INFO]: Added event to the user's vector store")
|
| 374 |
|
| 375 |
tool_outputs.append({
|
| 376 |
"tool_call_id": tool.id,
|
|
@@ -378,8 +373,9 @@ class Assistant:
|
|
| 378 |
})
|
| 379 |
elif tool.function.name == "msearch":
|
| 380 |
queries = json.loads(tool.function.arguments)['queries']
|
|
|
|
|
|
|
| 381 |
|
| 382 |
-
print(f"[MSEARCH]: Searching for {queries}")
|
| 383 |
tool_outputs.append({
|
| 384 |
"tool_call_id": tool.id,
|
| 385 |
"output": f"** retrieve any files related to: {queries} **"
|
|
@@ -395,14 +391,16 @@ class Assistant:
|
|
| 395 |
instruction = f"** Fetch files (mementos) from this thread's Memento vector_store ([id={self.cm.user_personal_memory.id}]) where the follow_up_on field matches the query date: {on} (ignore the time component, focus only on the date)**"
|
| 396 |
# f"** File search this threads' Memento vector_store ([id={self.cm.user_personal_memory.id}]) for the most relevant mementos based on the recent conversation history and context:{context} **"
|
| 397 |
|
| 398 |
-
|
|
|
|
| 399 |
tool_outputs.append({
|
| 400 |
"tool_call_id": tool.id,
|
| 401 |
"output": instruction
|
| 402 |
})
|
| 403 |
elif tool.function.name == "get_feedback_types":
|
| 404 |
selected_feedbacks = json.loads(tool.function.arguments)['feedbacks']
|
| 405 |
-
|
|
|
|
| 406 |
# feedback_types = FeedbackContent.select_random_types(self)
|
| 407 |
context = []
|
| 408 |
for feedback_type in selected_feedbacks:
|
|
@@ -412,7 +410,8 @@ class Assistant:
|
|
| 412 |
"tool_call_id": tool.id,
|
| 413 |
"output": f"** Build the feedback message using this context but dont include the feedback type: {context} **"
|
| 414 |
})
|
| 415 |
-
|
|
|
|
| 416 |
|
| 417 |
|
| 418 |
# Submit all tool outputs at once after collecting them in a list
|
|
@@ -423,11 +422,14 @@ class Assistant:
|
|
| 423 |
run_id=run.id,
|
| 424 |
tool_outputs=tool_outputs
|
| 425 |
)
|
| 426 |
-
|
|
|
|
| 427 |
except Exception as e:
|
| 428 |
-
|
|
|
|
| 429 |
else:
|
| 430 |
-
|
|
|
|
| 431 |
|
| 432 |
if run.status == 'completed':
|
| 433 |
messages = self.cm.client.beta.threads.messages.list(
|
|
@@ -435,10 +437,10 @@ class Assistant:
|
|
| 435 |
)
|
| 436 |
# print(messages)
|
| 437 |
elif run.status == 'requires_action':
|
| 438 |
-
|
| 439 |
run = self.call_tool(run, thread)
|
| 440 |
else:
|
| 441 |
-
|
| 442 |
return run
|
| 443 |
|
| 444 |
class GeneralAssistant(Assistant):
|
|
|
|
| 6 |
import random
|
| 7 |
import pandas as pd
|
| 8 |
from dotenv import load_dotenv
|
| 9 |
+
import logging
|
| 10 |
|
| 11 |
load_dotenv()
|
| 12 |
|
| 13 |
+
logger = logging.getLogger(__name__)
|
| 14 |
+
|
| 15 |
import requests
|
| 16 |
|
| 17 |
class SearchEngine:
|
|
|
|
| 306 |
thread_id=thread.id,
|
| 307 |
)
|
| 308 |
else:
|
| 309 |
+
logger.info(f"Run status: {run.status}", extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_process"})
|
| 310 |
return run
|
| 311 |
|
| 312 |
def call_tool(self, run, thread):
|
| 313 |
tool_outputs = []
|
| 314 |
+
logger.info(f"Required actions: {list(map(lambda x: f'{x.function.name}({x.function.arguments})', run.required_action.submit_tool_outputs.tool_calls))}",
|
| 315 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_call_tool"})
|
| 316 |
+
|
| 317 |
for tool in run.required_action.submit_tool_outputs.tool_calls:
|
| 318 |
if tool.function.name == "generate_coaching_plan":
|
| 319 |
user_challenge = json.loads(tool.function.arguments)
|
|
|
|
| 323 |
})
|
| 324 |
elif tool.function.name == "transition":
|
| 325 |
transitions = json.loads(tool.function.arguments)
|
| 326 |
+
logger.info(f"Transition: {transitions['from']} -> {transitions['to']}",
|
| 327 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_transition"})
|
| 328 |
|
| 329 |
if transitions['to'] == "REFLECTION STATE":
|
| 330 |
self.cm.user.matters_most.next()
|
|
|
|
| 340 |
current_time = get_current_datetime()
|
| 341 |
# replace time component of self.cm.state['date'] with the current time
|
| 342 |
self.cm.state['date'] = str(pd.to_datetime(self.cm.state['date']).replace(hour=current_time.hour, minute=current_time.minute, second=current_time.second))
|
| 343 |
+
logger.info(f"Current datetime: {self.cm.state['date']}",
|
| 344 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_get_date"})
|
| 345 |
|
| 346 |
tool_outputs.append({
|
| 347 |
"tool_call_id": tool.id,
|
|
|
|
| 351 |
json_string = json.loads(tool.function.arguments)
|
| 352 |
json_string['created'] = str(self.cm.state['date'])
|
| 353 |
json_string['updated'] = None
|
| 354 |
+
logger.info(f"New event: {json_string}",
|
| 355 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_create_event"})
|
| 356 |
|
| 357 |
# Create a folder for the user's mementos if it doesn't exist
|
| 358 |
user_mementos_folder = os.path.join("mementos", "to_upload", self.cm.user.user_id)
|
|
|
|
| 364 |
file_path = os.path.join(user_mementos_folder, f"{json_string['title']}.json")
|
| 365 |
|
| 366 |
# Save the JSON string as a file
|
| 367 |
+
with open(file_path, "wb") as json_file:
|
| 368 |
json.dump(json_string, json_file)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
|
| 370 |
tool_outputs.append({
|
| 371 |
"tool_call_id": tool.id,
|
|
|
|
| 373 |
})
|
| 374 |
elif tool.function.name == "msearch":
|
| 375 |
queries = json.loads(tool.function.arguments)['queries']
|
| 376 |
+
logger.info(f"Searching for: {queries}",
|
| 377 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_msearch"})
|
| 378 |
|
|
|
|
| 379 |
tool_outputs.append({
|
| 380 |
"tool_call_id": tool.id,
|
| 381 |
"output": f"** retrieve any files related to: {queries} **"
|
|
|
|
| 391 |
instruction = f"** Fetch files (mementos) from this thread's Memento vector_store ([id={self.cm.user_personal_memory.id}]) where the follow_up_on field matches the query date: {on} (ignore the time component, focus only on the date)**"
|
| 392 |
# f"** File search this threads' Memento vector_store ([id={self.cm.user_personal_memory.id}]) for the most relevant mementos based on the recent conversation history and context:{context} **"
|
| 393 |
|
| 394 |
+
logger.info(f"Getting mementos: {instruction}",
|
| 395 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_get_mementos"})
|
| 396 |
tool_outputs.append({
|
| 397 |
"tool_call_id": tool.id,
|
| 398 |
"output": instruction
|
| 399 |
})
|
| 400 |
elif tool.function.name == "get_feedback_types":
|
| 401 |
selected_feedbacks = json.loads(tool.function.arguments)['feedbacks']
|
| 402 |
+
logger.info(f"Selected feedbacks: {selected_feedbacks}",
|
| 403 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_get_feedback"})
|
| 404 |
# feedback_types = FeedbackContent.select_random_types(self)
|
| 405 |
context = []
|
| 406 |
for feedback_type in selected_feedbacks:
|
|
|
|
| 410 |
"tool_call_id": tool.id,
|
| 411 |
"output": f"** Build the feedback message using this context but dont include the feedback type: {context} **"
|
| 412 |
})
|
| 413 |
+
logger.info(f"Searched feedbacks: {context}",
|
| 414 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_get_feedback"})
|
| 415 |
|
| 416 |
|
| 417 |
# Submit all tool outputs at once after collecting them in a list
|
|
|
|
| 422 |
run_id=run.id,
|
| 423 |
tool_outputs=tool_outputs
|
| 424 |
)
|
| 425 |
+
logger.info("Tool outputs submitted successfully",
|
| 426 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_submit_tools"})
|
| 427 |
except Exception as e:
|
| 428 |
+
logger.error(f"Failed to submit tool outputs: {str(e)}",
|
| 429 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_submit_tools"})
|
| 430 |
else:
|
| 431 |
+
logger.warning("No tool outputs to submit",
|
| 432 |
+
extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_submit_tools"})
|
| 433 |
|
| 434 |
if run.status == 'completed':
|
| 435 |
messages = self.cm.client.beta.threads.messages.list(
|
|
|
|
| 437 |
)
|
| 438 |
# print(messages)
|
| 439 |
elif run.status == 'requires_action':
|
| 440 |
+
logger.info(f'[TOOL-R]: Calling tool for action', extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_submit_tools"})
|
| 441 |
run = self.call_tool(run, thread)
|
| 442 |
else:
|
| 443 |
+
logger.error("Something bad happened", run.status, extra={"user_id": self.cm.user.user_id, "endpoint": "assistant_submit_tools"})
|
| 444 |
return run
|
| 445 |
|
| 446 |
class GeneralAssistant(Assistant):
|
app/logs/app.log
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2024-11-21 17:11:30 [INFO]: HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
|
| 2 |
+
2024-11-21 17:11:30 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads "HTTP/1.1 200 OK"
|
| 3 |
+
2024-11-21 17:11:31 [INFO]: HTTP Request: POST https://api.openai.com/v1/vector_stores "HTTP/1.1 200 OK"
|
| 4 |
+
2024-11-21 17:11:31 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 5 |
+
2024-11-21 17:11:33 [INFO] [force_file_move]: Attempting to move file from users\to_upload\55ff3647-1694-4e78-a93a-091f3e099ced.pkl to users\data\55ff3647-1694-4e78-a93a-091f3e099ced.pkl
|
| 6 |
+
2024-11-21 17:11:33 [INFO] [force_file_move]: File moved successfully: users\to_upload\55ff3647-1694-4e78-a93a-091f3e099ced.pkl -> users\data\55ff3647-1694-4e78-a93a-091f3e099ced.pkl
|
| 7 |
+
2024-11-21 17:11:55 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 8 |
+
2024-11-21 17:11:55 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 9 |
+
2024-11-21 17:11:57 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 10 |
+
2024-11-21 17:11:57 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_4vqtD9bzQbYL8PkWLWhQbkzX "HTTP/1.1 200 OK"
|
| 11 |
+
2024-11-21 17:11:59 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_4vqtD9bzQbYL8PkWLWhQbkzX "HTTP/1.1 200 OK"
|
| 12 |
+
2024-11-21 17:12:01 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_4vqtD9bzQbYL8PkWLWhQbkzX "HTTP/1.1 200 OK"
|
| 13 |
+
2024-11-21 17:12:01 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_yIeB8kpysah4IUclSDncWUwQ "HTTP/1.1 200 OK"
|
| 14 |
+
2024-11-21 17:12:02 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 15 |
+
2024-11-21 17:12:02 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_ADGgK83XiDSKAFXPZsVFzovy "HTTP/1.1 200 OK"
|
| 16 |
+
2024-11-21 17:12:14 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 17 |
+
2024-11-21 17:12:15 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 18 |
+
2024-11-21 17:12:16 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 19 |
+
2024-11-21 17:12:16 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_4EBJVyqaHjVXyFuFyJdntH5C "HTTP/1.1 200 OK"
|
| 20 |
+
2024-11-21 17:12:18 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_4EBJVyqaHjVXyFuFyJdntH5C "HTTP/1.1 200 OK"
|
| 21 |
+
2024-11-21 17:12:18 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_5vZuOgoDZAF0NCrNhbzEvJ3Q "HTTP/1.1 200 OK"
|
| 22 |
+
2024-11-21 17:12:19 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 23 |
+
2024-11-21 17:12:19 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_pA8qWSTdoS7czr7SSuQ6mU8B "HTTP/1.1 200 OK"
|
| 24 |
+
2024-11-21 17:12:23 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 25 |
+
2024-11-21 17:12:23 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 26 |
+
2024-11-21 17:12:24 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 27 |
+
2024-11-21 17:12:24 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 28 |
+
2024-11-21 17:12:26 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 29 |
+
2024-11-21 17:12:27 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 30 |
+
2024-11-21 17:12:28 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 31 |
+
2024-11-21 17:12:29 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 32 |
+
2024-11-21 17:12:30 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 33 |
+
2024-11-21 17:12:30 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 34 |
+
2024-11-21 17:12:32 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 35 |
+
2024-11-21 17:12:32 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 36 |
+
2024-11-21 17:12:33 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 37 |
+
2024-11-21 17:12:35 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 38 |
+
2024-11-21 17:12:36 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_maKvI6YLrI0Z6M2b3fFEjmqk "HTTP/1.1 200 OK"
|
| 39 |
+
2024-11-21 17:12:37 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 40 |
+
2024-11-21 17:12:37 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_9uEDixJWrE4ndXe0QhJkBdMJ "HTTP/1.1 200 OK"
|
| 41 |
+
2024-11-21 17:12:38 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 42 |
+
2024-11-21 17:12:39 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_8l2bROG7oKHSiHQZPBbwNiUd "HTTP/1.1 200 OK"
|
| 43 |
+
2024-11-21 17:13:06 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 44 |
+
2024-11-21 17:13:06 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 45 |
+
2024-11-21 17:13:07 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 46 |
+
2024-11-21 17:13:07 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_DSXaUD73YLmxGUoGMB1D5Il0 "HTTP/1.1 200 OK"
|
| 47 |
+
2024-11-21 17:13:09 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_DSXaUD73YLmxGUoGMB1D5Il0 "HTTP/1.1 200 OK"
|
| 48 |
+
2024-11-21 17:13:09 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_PTAPFRFYg8qvdHQAwcqSpufZ "HTTP/1.1 200 OK"
|
| 49 |
+
2024-11-21 17:13:10 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 50 |
+
2024-11-21 17:13:11 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_WAbkOnBjHA49AUN26IlyJsYB "HTTP/1.1 200 OK"
|
| 51 |
+
2024-11-21 17:13:33 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 52 |
+
2024-11-21 17:13:34 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 53 |
+
2024-11-21 17:13:36 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 54 |
+
2024-11-21 17:13:36 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_NCw8XjxohLS8dl3tKhw7lQMe "HTTP/1.1 200 OK"
|
| 55 |
+
2024-11-21 17:13:38 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_NCw8XjxohLS8dl3tKhw7lQMe "HTTP/1.1 200 OK"
|
| 56 |
+
2024-11-21 17:13:39 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_NCw8XjxohLS8dl3tKhw7lQMe "HTTP/1.1 200 OK"
|
| 57 |
+
2024-11-21 17:13:43 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_SsageGl00fqLyonZISMZE1Km "HTTP/1.1 200 OK"
|
| 58 |
+
2024-11-21 17:13:43 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 59 |
+
2024-11-21 17:13:44 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_Pwr398fSZQDBl6tam3mEBVQa "HTTP/1.1 200 OK"
|
| 60 |
+
2024-11-21 17:14:02 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 61 |
+
2024-11-21 17:14:02 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 62 |
+
2024-11-21 17:14:03 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 63 |
+
2024-11-21 17:14:03 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 64 |
+
2024-11-21 17:14:04 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 65 |
+
2024-11-21 17:14:05 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 66 |
+
2024-11-21 17:14:06 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 67 |
+
2024-11-21 17:14:07 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 68 |
+
2024-11-21 17:14:08 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 69 |
+
2024-11-21 17:14:09 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 70 |
+
2024-11-21 17:14:10 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 71 |
+
2024-11-21 17:14:11 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 72 |
+
2024-11-21 17:14:12 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 73 |
+
2024-11-21 17:14:13 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 74 |
+
2024-11-21 17:14:14 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 75 |
+
2024-11-21 17:14:16 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FSQ48J5WrHn6dDmJ0BojEsuQ "HTTP/1.1 200 OK"
|
| 76 |
+
2024-11-21 17:14:16 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 77 |
+
2024-11-21 17:14:17 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_B7I9JgtRB5qstGJ9pbrMQHzO "HTTP/1.1 200 OK"
|
| 78 |
+
2024-11-21 17:14:17 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 79 |
+
2024-11-21 17:14:18 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_07u9Ax3qpG3Moe3a6EiQhHbR "HTTP/1.1 200 OK"
|
| 80 |
+
2024-11-21 17:14:18 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_epOvlrkVnPHh5q7mNP99nYFg "HTTP/1.1 200 OK"
|
| 81 |
+
2024-11-21 17:14:19 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 82 |
+
2024-11-21 17:14:20 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_07u9Ax3qpG3Moe3a6EiQhHbR "HTTP/1.1 200 OK"
|
| 83 |
+
2024-11-21 17:18:59 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 84 |
+
2024-11-21 17:19:00 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_07u9Ax3qpG3Moe3a6EiQhHbR "HTTP/1.1 200 OK"
|
| 85 |
+
2024-11-21 17:19:22 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 86 |
+
2024-11-21 17:19:23 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 87 |
+
2024-11-21 17:19:24 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 88 |
+
2024-11-21 17:19:24 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FCSTtem6LXzjTY4sO4UhFuC5 "HTTP/1.1 200 OK"
|
| 89 |
+
2024-11-21 17:19:26 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_FCSTtem6LXzjTY4sO4UhFuC5 "HTTP/1.1 200 OK"
|
| 90 |
+
2024-11-21 17:19:26 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_3L9h0R5w6rD1S6hEALudM5Ow "HTTP/1.1 200 OK"
|
| 91 |
+
2024-11-21 17:19:27 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 92 |
+
2024-11-21 17:19:27 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_9HUxe0bDMZ0uV3sDJnC2V4dn "HTTP/1.1 200 OK"
|
| 93 |
+
2024-11-21 17:19:49 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 94 |
+
2024-11-21 17:19:50 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 95 |
+
2024-11-21 17:19:51 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 96 |
+
2024-11-21 17:19:52 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_GS4Rh3fEJxRBauazWWJngsAL "HTTP/1.1 200 OK"
|
| 97 |
+
2024-11-21 17:19:53 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_GS4Rh3fEJxRBauazWWJngsAL "HTTP/1.1 200 OK"
|
| 98 |
+
2024-11-21 17:19:55 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_GS4Rh3fEJxRBauazWWJngsAL "HTTP/1.1 200 OK"
|
| 99 |
+
2024-11-21 17:19:55 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_fPiP6mS6UsUMecK6nL4wcTb0 "HTTP/1.1 200 OK"
|
| 100 |
+
2024-11-21 17:19:55 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 101 |
+
2024-11-21 17:19:56 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_IUlTk82fMuuA7Nv1XS3yc2LC "HTTP/1.1 200 OK"
|
| 102 |
+
2024-11-21 17:20:54 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 103 |
+
2024-11-21 17:20:54 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 104 |
+
2024-11-21 17:20:55 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 105 |
+
2024-11-21 17:20:56 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 106 |
+
2024-11-21 17:20:56 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 107 |
+
2024-11-21 17:20:58 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 108 |
+
2024-11-21 17:20:59 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 109 |
+
2024-11-21 17:20:59 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 110 |
+
2024-11-21 17:21:01 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 111 |
+
2024-11-21 17:21:02 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 112 |
+
2024-11-21 17:21:02 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 113 |
+
2024-11-21 17:21:04 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 114 |
+
2024-11-21 17:21:05 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 115 |
+
2024-11-21 17:21:05 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 116 |
+
2024-11-21 17:21:07 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_uAs5FPg6kXJNFjmqCxNSHRhV "HTTP/1.1 200 OK"
|
| 117 |
+
2024-11-21 17:21:07 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 118 |
+
2024-11-21 17:21:08 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_BsjN5VNl4aVYMsFpw42qCSip "HTTP/1.1 200 OK"
|
| 119 |
+
2024-11-21 17:21:08 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 120 |
+
2024-11-21 17:21:08 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_EjBC98vWPxgDOqVD9UDbew0h "HTTP/1.1 200 OK"
|
| 121 |
+
2024-11-21 17:21:09 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_FLM7aUUADX1vJccnTCMqsn1X "HTTP/1.1 200 OK"
|
| 122 |
+
2024-11-21 17:21:09 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 123 |
+
2024-11-21 17:21:10 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_EjBC98vWPxgDOqVD9UDbew0h "HTTP/1.1 200 OK"
|
| 124 |
+
2024-11-21 17:21:11 [INFO] [force_file_move]: Attempting to move file from users\to_upload\55ff3647-1694-4e78-a93a-091f3e099ced.pkl to users\data\55ff3647-1694-4e78-a93a-091f3e099ced.pkl
|
| 125 |
+
2024-11-21 17:21:11 [INFO] [force_file_move]: File moved successfully: users\to_upload\55ff3647-1694-4e78-a93a-091f3e099ced.pkl -> users\data\55ff3647-1694-4e78-a93a-091f3e099ced.pkl
|
| 126 |
+
2024-11-21 17:21:55 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 127 |
+
2024-11-21 17:21:55 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 128 |
+
2024-11-21 17:21:56 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 129 |
+
2024-11-21 17:21:57 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_3ZeS8WBc4ZrsvZb3tu8jWnaF "HTTP/1.1 200 OK"
|
| 130 |
+
2024-11-21 17:21:58 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_3ZeS8WBc4ZrsvZb3tu8jWnaF "HTTP/1.1 200 OK"
|
| 131 |
+
2024-11-21 17:21:59 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_aNSTgSog6sTFmWDvkUFN18xA "HTTP/1.1 200 OK"
|
| 132 |
+
2024-11-21 17:21:59 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 133 |
+
2024-11-21 17:22:00 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_m64xoQQxzX5jXauA5cVKI7ZV "HTTP/1.1 200 OK"
|
| 134 |
+
2024-11-21 17:22:00 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_y6OtQR1Czx0rk9WBTYN1ykC6 "HTTP/1.1 200 OK"
|
| 135 |
+
2024-11-21 17:22:29 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 136 |
+
2024-11-21 17:22:29 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 137 |
+
2024-11-21 17:22:30 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 138 |
+
2024-11-21 17:22:31 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_ChdY9skAIAKyxDDa6dzuO9dq "HTTP/1.1 200 OK"
|
| 139 |
+
2024-11-21 17:22:32 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_ChdY9skAIAKyxDDa6dzuO9dq "HTTP/1.1 200 OK"
|
| 140 |
+
2024-11-21 17:22:34 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_ChdY9skAIAKyxDDa6dzuO9dq "HTTP/1.1 200 OK"
|
| 141 |
+
2024-11-21 17:22:35 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_XI6OSseHzZIsLZzBQlIHbH3t "HTTP/1.1 200 OK"
|
| 142 |
+
2024-11-21 17:22:35 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 143 |
+
2024-11-21 17:22:36 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_m64xoQQxzX5jXauA5cVKI7ZV "HTTP/1.1 200 OK"
|
| 144 |
+
2024-11-21 17:22:36 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_YPfA0lng5kX2ZSk7rr8ue5rh "HTTP/1.1 200 OK"
|
| 145 |
+
2024-11-21 17:23:10 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 146 |
+
2024-11-21 17:23:11 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 147 |
+
2024-11-21 17:23:11 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 148 |
+
2024-11-21 17:23:12 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs "HTTP/1.1 200 OK"
|
| 149 |
+
2024-11-21 17:23:13 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 150 |
+
2024-11-21 17:23:14 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 151 |
+
2024-11-21 17:23:15 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 152 |
+
2024-11-21 17:23:16 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 153 |
+
2024-11-21 17:23:17 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 154 |
+
2024-11-21 17:23:18 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 155 |
+
2024-11-21 17:23:19 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 156 |
+
2024-11-21 17:23:21 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 157 |
+
2024-11-21 17:23:22 [INFO]: HTTP Request: POST https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP/submit_tool_outputs "HTTP/1.1 200 OK"
|
| 158 |
+
2024-11-21 17:23:22 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 159 |
+
2024-11-21 17:23:23 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 160 |
+
2024-11-21 17:23:25 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 161 |
+
2024-11-21 17:23:27 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 162 |
+
2024-11-21 17:23:28 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 163 |
+
2024-11-21 17:23:30 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 164 |
+
2024-11-21 17:23:33 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/runs/run_xlXtfSUKmigYcZk1WBxHpiOP "HTTP/1.1 200 OK"
|
| 165 |
+
2024-11-21 17:23:34 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages "HTTP/1.1 200 OK"
|
| 166 |
+
2024-11-21 17:23:35 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_jzMnbvvGwVQYSl9n6eMfDn1I "HTTP/1.1 200 OK"
|
| 167 |
+
2024-11-21 17:23:35 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 168 |
+
2024-11-21 17:23:35 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_m64xoQQxzX5jXauA5cVKI7ZV "HTTP/1.1 200 OK"
|
| 169 |
+
2024-11-21 17:23:36 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_WfXx665UszjcIm24ty2tTIms "HTTP/1.1 200 OK"
|
| 170 |
+
2024-11-21 17:23:36 [INFO]: HTTP Request: DELETE https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages/msg_DQNvjP4AYI5B4E738HRHuJyB "HTTP/1.1 200 OK"
|
| 171 |
+
2024-11-21 17:23:36 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc "HTTP/1.1 200 OK"
|
| 172 |
+
2024-11-21 17:23:37 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_m64xoQQxzX5jXauA5cVKI7ZV "HTTP/1.1 200 OK"
|
| 173 |
+
2024-11-21 17:23:37 [INFO]: HTTP Request: GET https://api.openai.com/v1/threads/thread_cOIGiiEQLrtE1CVFMYn1FwuX/messages?order=asc&after=msg_WfXx665UszjcIm24ty2tTIms "HTTP/1.1 200 OK"
|
| 174 |
+
2024-11-21 17:23:39 [INFO] [force_file_move]: Attempting to move file from users\to_upload\55ff3647-1694-4e78-a93a-091f3e099ced.pkl to users\data\55ff3647-1694-4e78-a93a-091f3e099ced.pkl
|
| 175 |
+
2024-11-21 17:23:39 [INFO] [force_file_move]: File moved successfully: users\to_upload\55ff3647-1694-4e78-a93a-091f3e099ced.pkl -> users\data\55ff3647-1694-4e78-a93a-091f3e099ced.pkl
|
app/logs/users/55ff3647-1694-4e78-a93a-091f3e099ced.log
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2024-11-21 17:11:22,003 [INFO] [/create_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Creating new user
|
| 2 |
+
2024-11-21 17:11:22,140 [INFO] [get_user_info] [55ff3647-1694-4e78-a93a-091f3e099ced]: Retrieving user info for 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 3 |
+
2024-11-21 17:11:22,367 [INFO] [get_user_info] [55ff3647-1694-4e78-a93a-091f3e099ced]: User info retrieved successfully for 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 4 |
+
2024-11-21 17:11:22,384 [INFO] [circular_queue_next] [55ff3647-1694-4e78-a93a-091f3e099ced]: [Reflection Topic] [Previous]: None -> [Current]: Career growth 💼
|
| 5 |
+
2024-11-21 17:11:22,384 [INFO] [user_init] [55ff3647-1694-4e78-a93a-091f3e099ced]: Matters most topics: ['Career growth 💼', 'Better relationships ❤️', 'Personal growth 🪴', 'Health & wellness 🍎', 'Mental well-being 🧠']
|
| 6 |
+
2024-11-21 17:11:31,908 [INFO] [conversation_init] [55ff3647-1694-4e78-a93a-091f3e099ced]: Initializing conversation state
|
| 7 |
+
2024-11-21 17:11:31,908 [INFO] [/create_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Created pickle file for user
|
| 8 |
+
2024-11-21 17:11:31,908 [INFO] [/create_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Created temp memento folder for user
|
| 9 |
+
2024-11-21 17:11:31,908 [INFO] [upload_file_to_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploading file 55ff3647-1694-4e78-a93a-091f3e099ced.pkl to S3
|
| 10 |
+
2024-11-21 17:11:33,632 [INFO] [upload_file_to_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: File 55ff3647-1694-4e78-a93a-091f3e099ced.pkl uploaded successfully to S3
|
| 11 |
+
2024-11-21 17:11:33,655 [INFO] [/create_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Successfully created user
|
| 12 |
+
2024-11-21 17:11:33,655 [INFO] [/create_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 13 |
+
2024-11-21 17:11:54,684 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 14 |
+
2024-11-21 17:11:54,684 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 15 |
+
2024-11-21 17:11:54,985 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 16 |
+
2024-11-21 17:12:02,385 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': "Hello, Yew Wai! \n\nI'm Coach Steve, inspired by the innovative spirit of *Steve Jobs*. \n\nI'm here to help you achieve your ideal life—focusing on your career growth while nurturing your relationships and personal development. I understand that as the founder of ourcoach, you're navigating the challenges of building AI functionality while maintaining a supportive relationship with Karina. Remember, each challenge is an opportunity for growth and innovation!\n\nLet's focus on your goals and embrace your journey. Let's embark on this inspiring path together!"}
|
| 17 |
+
2024-11-21 17:12:02,385 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: Hello, Yew Wai!
|
| 18 |
+
|
| 19 |
+
I'm Coach Steve, inspired by the innovative spirit of *Steve Jobs*.
|
| 20 |
+
|
| 21 |
+
I'm here to help you achieve your ideal life—focusing on your career growth while nurturing your relationships and personal development. I understand that as the founder of ourcoach, you're navigating the challenges of building AI functionality while maintaining a supportive relationship with Karina. Remember, each challenge is an opportunity for growth and innovation!
|
| 22 |
+
|
| 23 |
+
Let's focus on your goals and embrace your journey. Let's embark on this inspiring path together!
|
| 24 |
+
2024-11-21 17:12:02,385 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 25 |
+
2024-11-21 17:12:13,935 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 26 |
+
2024-11-21 17:12:13,935 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 27 |
+
2024-11-21 17:12:14,235 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 28 |
+
2024-11-21 17:12:19,435 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': "Here's how you can maximize the experience on *ourcoach*:\n\n1.\u2060 📌 *\u2060Pin this Chat*: Keep this conversation easily accessible.\n\n2.\u2060 \u2060📅 *Engage Daily*: Consistency is key—check in daily for reflections and insights.\n\n3.\u2060 \u2060💬 *Be Open and Honest*: Share your thoughts and feelings openly. \n\n4.\u2060 \u2060✅ *Stay Accountable*: Track your progress and speak to a Growth Guide: https://app.staging.ourcoach.ai/\n\n"}
|
| 29 |
+
2024-11-21 17:12:19,435 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: Here's how you can maximize the experience on *ourcoach*:
|
| 30 |
+
|
| 31 |
+
1. 📌 *Pin this Chat*: Keep this conversation easily accessible.
|
| 32 |
+
|
| 33 |
+
2. 📅 *Engage Daily*: Consistency is key—check in daily for reflections and insights.
|
| 34 |
+
|
| 35 |
+
3. 💬 *Be Open and Honest*: Share your thoughts and feelings openly.
|
| 36 |
+
|
| 37 |
+
4. ✅ *Stay Accountable*: Track your progress and speak to a Growth Guide: https://app.staging.ourcoach.ai/
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
2024-11-21 17:12:19,435 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 41 |
+
2024-11-21 17:12:22,528 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 42 |
+
2024-11-21 17:12:22,528 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 43 |
+
2024-11-21 17:12:22,819 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 44 |
+
2024-11-21 17:12:26,534 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['transition({"from":"INTRODUCTION STATE","to":"REFLECTION STATE"})']
|
| 45 |
+
2024-11-21 17:12:26,534 [INFO] [assistant_transition] [55ff3647-1694-4e78-a93a-091f3e099ced]: Transition: INTRODUCTION STATE -> REFLECTION STATE
|
| 46 |
+
2024-11-21 17:12:26,534 [INFO] [circular_queue_next] [55ff3647-1694-4e78-a93a-091f3e099ced]: [Reflection Topic] [Previous]: Career growth 💼 -> [Current]: Better relationships ❤️
|
| 47 |
+
2024-11-21 17:12:29,719 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 48 |
+
2024-11-21 17:12:29,719 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 49 |
+
2024-11-21 17:12:29,719 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_date({})']
|
| 50 |
+
2024-11-21 17:12:29,719 [INFO] [assistant_get_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Current datetime: 2024-11-21 17:12:29
|
| 51 |
+
2024-11-21 17:12:32,402 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 52 |
+
2024-11-21 17:12:32,402 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 53 |
+
2024-11-21 17:12:32,402 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_feedback_types({"feedbacks":[{"feedback_type":"Tips & Advice","search_query":"career growth tips"},{"feedback_type":"Encouragement","search_query":"motivational messages for founders"},{"feedback_type":"Book/Podcast Recommendations","search_query":"best books for personal growth"}]})']
|
| 54 |
+
2024-11-21 17:12:32,402 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Selected feedbacks: [{'feedback_type': 'Tips & Advice', 'search_query': 'career growth tips'}, {'feedback_type': 'Encouragement', 'search_query': 'motivational messages for founders'}, {'feedback_type': 'Book/Podcast Recommendations', 'search_query': 'best books for personal growth'}]
|
| 55 |
+
2024-11-21 17:12:32,402 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Searched feedbacks: ['Feedback Type: Tips & Advice, Feedback On: career growth tips', 'Feedback Type: Encouragement, Feedback On: motivational messages for founders', 'Feedback Type: Book/Podcast Recommendations, Feedback On: best books for personal growth']
|
| 56 |
+
2024-11-21 17:12:37,020 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 57 |
+
2024-11-21 17:12:39,017 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': '☀️ Hey, Yew Wai! \n\n*On a scale from 1 (Not at all) to 5 (Extremely), how aligned do you feel with your career growth goals as the founder of ourcoach right now?* \n\n<br>\n**What specific areas do you feel you need to focus on to enhance your growth?**'}
|
| 58 |
+
2024-11-21 17:12:39,018 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: ☀️ Hey, Yew Wai!
|
| 59 |
+
|
| 60 |
+
*On a scale from 1 (Not at all) to 5 (Extremely), how aligned do you feel with your career growth goals as the founder of ourcoach right now?*
|
| 61 |
+
|
| 62 |
+
<br>
|
| 63 |
+
**What specific areas do you feel you need to focus on to enhance your growth?**
|
| 64 |
+
2024-11-21 17:12:39,018 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 65 |
+
2024-11-21 17:13:05,762 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 66 |
+
2024-11-21 17:13:05,762 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 67 |
+
2024-11-21 17:13:06,068 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 68 |
+
2024-11-21 17:13:11,170 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': "That's great to hear that you're feeling aligned with your career growth goals! \n\nGetting that MVP out by the end of the year is an exciting and crucial step. \n\n**What strategies do you think will help you achieve this goal with the timeline you have in mind?**"}
|
| 69 |
+
2024-11-21 17:13:11,170 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: That's great to hear that you're feeling aligned with your career growth goals!
|
| 70 |
+
|
| 71 |
+
Getting that MVP out by the end of the year is an exciting and crucial step.
|
| 72 |
+
|
| 73 |
+
**What strategies do you think will help you achieve this goal with the timeline you have in mind?**
|
| 74 |
+
2024-11-21 17:13:11,170 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 75 |
+
2024-11-21 17:13:32,969 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 76 |
+
2024-11-21 17:13:32,969 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 77 |
+
2024-11-21 17:13:33,099 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 78 |
+
2024-11-21 17:13:44,289 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': 'You\'re definitely on the right track, collaborating with your team is key to reaching that MVP goal! \n\nHere are a few suggestions to keep the momentum going:\n\n- 💡 Focusing on clear communication will help ensure everyone is on the same page as you work towards your deadline.\n \n- 🌈 Celebrate small victories with your team to maintain motivation and boost morale during this busy time.\n \n- 📚 Consider reading books like "The Lean Startup" for practical insights on building your MVP effectively.\n\nKeep pushing forward, Yew Wai! You\'re doing amazing work!'}
|
| 79 |
+
2024-11-21 17:13:44,289 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: You're definitely on the right track, collaborating with your team is key to reaching that MVP goal!
|
| 80 |
+
|
| 81 |
+
Here are a few suggestions to keep the momentum going:
|
| 82 |
+
|
| 83 |
+
- 💡 Focusing on clear communication will help ensure everyone is on the same page as you work towards your deadline.
|
| 84 |
+
|
| 85 |
+
- 🌈 Celebrate small victories with your team to maintain motivation and boost morale during this busy time.
|
| 86 |
+
|
| 87 |
+
- 📚 Consider reading books like "The Lean Startup" for practical insights on building your MVP effectively.
|
| 88 |
+
|
| 89 |
+
Keep pushing forward, Yew Wai! You're doing amazing work!
|
| 90 |
+
2024-11-21 17:13:44,289 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 91 |
+
2024-11-21 17:14:01,949 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing date change request, new date: 22/11/2024 Fri 10:00:00
|
| 92 |
+
2024-11-21 17:14:01,949 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 93 |
+
2024-11-21 17:14:02,083 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 94 |
+
2024-11-21 17:14:02,083 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Changing date from 2024-11-21 Thu 17:11:30 to 22/11/2024 Fri 10:00:00
|
| 95 |
+
2024-11-21 17:14:02,083 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Today's reflection topic is Better relationships ❤️
|
| 96 |
+
2024-11-21 17:14:06,134 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_mementos({"queries":["relationship support from Karina","dinners booked by Karina"],"on":"2024-11-22"})']
|
| 97 |
+
2024-11-21 17:14:06,134 [INFO] [assistant_get_mementos] [55ff3647-1694-4e78-a93a-091f3e099ced]: Getting mementos: ** Fetch files (mementos) from this thread's Memento vector_store ([id=vs_FY5RE6yKKujkEKgIvb8WYlSy]) where the follow_up_on field matches the query date: 2024-11-22 (ignore the time component, focus only on the date)**
|
| 98 |
+
2024-11-21 17:14:09,069 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 99 |
+
2024-11-21 17:14:09,069 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 100 |
+
2024-11-21 17:14:09,069 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['transition({"from":"IDLE STATE","to":"REFLECTION STATE"})']
|
| 101 |
+
2024-11-21 17:14:09,069 [INFO] [assistant_transition] [55ff3647-1694-4e78-a93a-091f3e099ced]: Transition: IDLE STATE -> REFLECTION STATE
|
| 102 |
+
2024-11-21 17:14:09,069 [INFO] [circular_queue_next] [55ff3647-1694-4e78-a93a-091f3e099ced]: [Reflection Topic] [Previous]: Career growth 💼 -> [Current]: Better relationships ❤️
|
| 103 |
+
2024-11-21 17:14:12,031 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 104 |
+
2024-11-21 17:14:12,031 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 105 |
+
2024-11-21 17:14:12,031 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_feedback_types({"feedbacks":[{"feedback_type":"Tips & Advice","search_query":"building better relationships tips"},{"feedback_type":"Encouragement","search_query":"motivational messages for relationships"},{"feedback_type":"Book/Podcast Recommendations","search_query":"best books for improving relationships"}]})']
|
| 106 |
+
2024-11-21 17:14:12,031 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Selected feedbacks: [{'feedback_type': 'Tips & Advice', 'search_query': 'building better relationships tips'}, {'feedback_type': 'Encouragement', 'search_query': 'motivational messages for relationships'}, {'feedback_type': 'Book/Podcast Recommendations', 'search_query': 'best books for improving relationships'}]
|
| 107 |
+
2024-11-21 17:14:12,031 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Searched feedbacks: ['Feedback Type: Tips & Advice, Feedback On: building better relationships tips', 'Feedback Type: Encouragement, Feedback On: motivational messages for relationships', 'Feedback Type: Book/Podcast Recommendations, Feedback On: best books for improving relationships']
|
| 108 |
+
2024-11-21 17:14:16,567 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 109 |
+
2024-11-21 17:14:20,381 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Date Updated: 22/11/2024 Fri 10:00:00
|
| 110 |
+
2024-11-21 17:14:20,381 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Date changed successfully for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 111 |
+
2024-11-21 17:14:20,383 [INFO] [upload_mementos_to_db] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploading mementos to DB for user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 112 |
+
2024-11-21 17:14:20,567 [ERROR] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Failed to upload mementos to DB for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 113 |
+
2024-11-21 17:14:20,567 [ERROR] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Error changing date for user 55ff3647-1694-4e78-a93a-091f3e099ced: 500: Failed to upload mementos to DB for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 114 |
+
Traceback (most recent call last):
|
| 115 |
+
File "C:\Users\shage\ourcoach-ai-core\app\main.py", line 346, in change_date
|
| 116 |
+
raise HTTPException(
|
| 117 |
+
fastapi.exceptions.HTTPException: 500: Failed to upload mementos to DB for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 118 |
+
2024-11-21 17:14:20,567 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 500
|
| 119 |
+
2024-11-21 17:18:59,090 [INFO] [/get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Getting user
|
| 120 |
+
2024-11-21 17:18:59,091 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 121 |
+
2024-11-21 17:18:59,219 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 122 |
+
2024-11-21 17:18:59,219 [INFO] [/get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Successfully retrieved user
|
| 123 |
+
2024-11-21 17:19:00,234 [INFO] [/get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: GET Status: 200
|
| 124 |
+
2024-11-21 17:19:22,412 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 125 |
+
2024-11-21 17:19:22,412 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 126 |
+
2024-11-21 17:19:22,536 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 127 |
+
2024-11-21 17:19:27,569 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': "That's wonderful to hear that you're feeling very satisfied with the support from Karina! \n\n**In what ways do you think you can further nurture this supportive environment in your relationship?**"}
|
| 128 |
+
2024-11-21 17:19:27,569 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: That's wonderful to hear that you're feeling very satisfied with the support from Karina!
|
| 129 |
+
|
| 130 |
+
**In what ways do you think you can further nurture this supportive environment in your relationship?**
|
| 131 |
+
2024-11-21 17:19:27,569 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 132 |
+
2024-11-21 17:19:49,386 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 133 |
+
2024-11-21 17:19:49,386 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 134 |
+
2024-11-21 17:19:49,519 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 135 |
+
2024-11-21 17:19:56,403 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': 'That sounds like a lovely way to nurture your relationship! \n\nHere are a few thoughts to enhance your romantic dinner experience:\n\n- 💡 Planning a surprise element during dinner can make it memorable, like a little gift or a heartfelt note.\n\n- 🌈 Expressing your appreciation for Karina during the dinner can deepen your connection and strengthen your bond.\n\n- 📚 Consider reading "The 5 Love Languages" for insights into enhancing your relationship even further.\n\nEnjoy your dinner tomorrow night, Yew Wai! You\'re doing an amazing job at building a supportive and loving relationship!'}
|
| 136 |
+
2024-11-21 17:19:56,403 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: That sounds like a lovely way to nurture your relationship!
|
| 137 |
+
|
| 138 |
+
Here are a few thoughts to enhance your romantic dinner experience:
|
| 139 |
+
|
| 140 |
+
- 💡 Planning a surprise element during dinner can make it memorable, like a little gift or a heartfelt note.
|
| 141 |
+
|
| 142 |
+
- 🌈 Expressing your appreciation for Karina during the dinner can deepen your connection and strengthen your bond.
|
| 143 |
+
|
| 144 |
+
- 📚 Consider reading "The 5 Love Languages" for insights into enhancing your relationship even further.
|
| 145 |
+
|
| 146 |
+
Enjoy your dinner tomorrow night, Yew Wai! You're doing an amazing job at building a supportive and loving relationship!
|
| 147 |
+
2024-11-21 17:19:56,403 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 148 |
+
2024-11-21 17:20:53,887 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing date change request, new date: 23/11/2024 Sat 10:00:00
|
| 149 |
+
2024-11-21 17:20:53,887 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 150 |
+
2024-11-21 17:20:54,036 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 151 |
+
2024-11-21 17:20:54,036 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Changing date from 2024-11-21 Thu 17:11:30 to 23/11/2024 Sat 10:00:00
|
| 152 |
+
2024-11-21 17:20:54,036 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Today's reflection topic is Better relationships ❤️
|
| 153 |
+
2024-11-21 17:20:58,448 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_mementos({"queries":["romantic dinner with Karina"],"on":"2024-11-23"})']
|
| 154 |
+
2024-11-21 17:20:58,448 [INFO] [assistant_get_mementos] [55ff3647-1694-4e78-a93a-091f3e099ced]: Getting mementos: ** Fetch files (mementos) from this thread's Memento vector_store ([id=vs_FY5RE6yKKujkEKgIvb8WYlSy]) where the follow_up_on field matches the query date: 2024-11-23 (ignore the time component, focus only on the date)**
|
| 155 |
+
2024-11-21 17:21:01,417 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 156 |
+
2024-11-21 17:21:01,417 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 157 |
+
2024-11-21 17:21:01,417 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['transition({"from":"IDLE STATE","to":"REFLECTION STATE"})']
|
| 158 |
+
2024-11-21 17:21:01,417 [INFO] [assistant_transition] [55ff3647-1694-4e78-a93a-091f3e099ced]: Transition: IDLE STATE -> REFLECTION STATE
|
| 159 |
+
2024-11-21 17:21:01,417 [INFO] [circular_queue_next] [55ff3647-1694-4e78-a93a-091f3e099ced]: [Reflection Topic] [Previous]: Career growth 💼 -> [Current]: Better relationships ❤️
|
| 160 |
+
2024-11-21 17:21:04,413 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 161 |
+
2024-11-21 17:21:04,413 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 162 |
+
2024-11-21 17:21:04,413 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_feedback_types({"feedbacks":[{"feedback_type":"Tips & Advice","search_query":"maintaining healthy relationships tips"},{"feedback_type":"Encouragement","search_query":"motivational messages for couples"},{"feedback_type":"Book/Podcast Recommendations","search_query":"best books for couples"}]})']
|
| 163 |
+
2024-11-21 17:21:04,413 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Selected feedbacks: [{'feedback_type': 'Tips & Advice', 'search_query': 'maintaining healthy relationships tips'}, {'feedback_type': 'Encouragement', 'search_query': 'motivational messages for couples'}, {'feedback_type': 'Book/Podcast Recommendations', 'search_query': 'best books for couples'}]
|
| 164 |
+
2024-11-21 17:21:04,413 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Searched feedbacks: ['Feedback Type: Tips & Advice, Feedback On: maintaining healthy relationships tips', 'Feedback Type: Encouragement, Feedback On: motivational messages for couples', 'Feedback Type: Book/Podcast Recommendations, Feedback On: best books for couples']
|
| 165 |
+
2024-11-21 17:21:07,353 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 166 |
+
2024-11-21 17:21:10,320 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Date Updated: 23/11/2024 Sat 10:00:00
|
| 167 |
+
2024-11-21 17:21:10,320 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Date changed successfully for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 168 |
+
2024-11-21 17:21:10,320 [INFO] [upload_mementos_to_db] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploading mementos to DB for user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 169 |
+
2024-11-21 17:21:10,487 [INFO] [upload_mementos_to_db] [55ff3647-1694-4e78-a93a-091f3e099ced]: Successfully uploaded mementos for user 55ff3647-1694-4e78-a93a-091f3e099ced to DB
|
| 170 |
+
2024-11-21 17:21:10,487 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploaded mementos to DB for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 171 |
+
2024-11-21 17:21:10,487 [INFO] [update_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Updating user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 172 |
+
2024-11-21 17:21:10,495 [INFO] [upload_file_to_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploading file 55ff3647-1694-4e78-a93a-091f3e099ced.pkl to S3
|
| 173 |
+
2024-11-21 17:21:11,220 [INFO] [upload_file_to_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: File 55ff3647-1694-4e78-a93a-091f3e099ced.pkl uploaded successfully to S3
|
| 174 |
+
2024-11-21 17:21:11,220 [INFO] [update_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced updated successfully in S3
|
| 175 |
+
2024-11-21 17:21:11,220 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 176 |
+
2024-11-21 17:21:52,980 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 177 |
+
2024-11-21 17:21:52,980 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 178 |
+
2024-11-21 17:21:53,272 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced not found locally. Attempting to download from S3
|
| 179 |
+
2024-11-21 17:21:53,272 [INFO] [download_file_from_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: Downloading file 55ff3647-1694-4e78-a93a-091f3e099ced.pkl from S3 bucket core-ai-assets
|
| 180 |
+
2024-11-21 17:21:54,955 [INFO] [download_file_from_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: File 55ff3647-1694-4e78-a93a-091f3e099ced.pkl downloaded successfully from S3
|
| 181 |
+
2024-11-21 17:21:54,958 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Download success: True
|
| 182 |
+
2024-11-21 17:21:54,958 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from S3
|
| 183 |
+
2024-11-21 17:22:00,486 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': "I'm glad to hear that you had a fantastic time during your dinner with Karina! \n\n**What aspects of the evening do you think contributed most to the great experience you shared?**"}
|
| 184 |
+
2024-11-21 17:22:00,486 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: I'm glad to hear that you had a fantastic time during your dinner with Karina!
|
| 185 |
+
|
| 186 |
+
**What aspects of the evening do you think contributed most to the great experience you shared?**
|
| 187 |
+
2024-11-21 17:22:00,486 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 188 |
+
2024-11-21 17:22:28,355 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing chat request
|
| 189 |
+
2024-11-21 17:22:28,355 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 190 |
+
2024-11-21 17:22:28,655 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 191 |
+
2024-11-21 17:22:36,685 [INFO] [user_send_message] [55ff3647-1694-4e78-a93a-091f3e099ced]: Response: {'role': 'assistant', 'content': 'Sounds like the perfect combination for an enjoyable evening! \n\nHere are a few ideas to keep that positive energy flowing in your relationship:\n\n- 💡 Continue to explore new dining experiences together to create more memorable moments.\n\n- 🌈 Remember to express your appreciation to Karina for being such great company; it can deepen your bond.\n\n- 📚 A book like "Hold Me Tight" can provide insights into nurturing emotional connection in your relationship.\n\nKeep cherishing those wonderful moments together, Yew Wai! You\'re doing an amazing job in building a strong and loving relationship!'}
|
| 192 |
+
2024-11-21 17:22:36,685 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Assistant: Sounds like the perfect combination for an enjoyable evening!
|
| 193 |
+
|
| 194 |
+
Here are a few ideas to keep that positive energy flowing in your relationship:
|
| 195 |
+
|
| 196 |
+
- 💡 Continue to explore new dining experiences together to create more memorable moments.
|
| 197 |
+
|
| 198 |
+
- 🌈 Remember to express your appreciation to Karina for being such great company; it can deepen your bond.
|
| 199 |
+
|
| 200 |
+
- 📚 A book like "Hold Me Tight" can provide insights into nurturing emotional connection in your relationship.
|
| 201 |
+
|
| 202 |
+
Keep cherishing those wonderful moments together, Yew Wai! You're doing an amazing job in building a strong and loving relationship!
|
| 203 |
+
2024-11-21 17:22:36,685 [INFO] [/chat] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
| 204 |
+
2024-11-21 17:23:10,087 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Processing date change request, new date: 24/11/2024 Sun 10:00:00
|
| 205 |
+
2024-11-21 17:23:10,087 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Fetching user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 206 |
+
2024-11-21 17:23:10,387 [INFO] [get_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced loaded successfully from local storage
|
| 207 |
+
2024-11-21 17:23:10,387 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Changing date from 23/11/2024 Sat 10:00:00 to 24/11/2024 Sun 10:00:00
|
| 208 |
+
2024-11-21 17:23:10,387 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Today's reflection topic is Personal growth 🪴
|
| 209 |
+
2024-11-21 17:23:15,036 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_mementos({"queries":[],"on":"2024-11-24"})']
|
| 210 |
+
2024-11-21 17:23:15,036 [INFO] [assistant_get_mementos] [55ff3647-1694-4e78-a93a-091f3e099ced]: Getting mementos: ** Fetch files (mementos) from this thread's Memento vector_store ([id=vs_FY5RE6yKKujkEKgIvb8WYlSy]) where the follow_up_on field matches the query date: 2024-11-24 (ignore the time component, focus only on the date)**
|
| 211 |
+
2024-11-21 17:23:18,027 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 212 |
+
2024-11-21 17:23:18,027 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 213 |
+
2024-11-21 17:23:18,027 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['transition({"from":"IDLE STATE","to":"REFLECTION STATE"})']
|
| 214 |
+
2024-11-21 17:23:18,027 [INFO] [assistant_transition] [55ff3647-1694-4e78-a93a-091f3e099ced]: Transition: IDLE STATE -> REFLECTION STATE
|
| 215 |
+
2024-11-21 17:23:18,027 [INFO] [circular_queue_next] [55ff3647-1694-4e78-a93a-091f3e099ced]: [Reflection Topic] [Previous]: Better relationships ❤️ -> [Current]: Personal growth 🪴
|
| 216 |
+
2024-11-21 17:23:21,295 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 217 |
+
2024-11-21 17:23:21,295 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: [TOOL-R]: Calling tool for action
|
| 218 |
+
2024-11-21 17:23:21,295 [INFO] [assistant_call_tool] [55ff3647-1694-4e78-a93a-091f3e099ced]: Required actions: ['get_feedback_types({"feedbacks":[{"feedback_type":"Tips & Advice","search_query":"strategies for personal growth"},{"feedback_type":"Encouragement","search_query":"motivational messages for self-improvement"},{"feedback_type":"Book/Podcast Recommendations","search_query":"best personal growth books"}]})']
|
| 219 |
+
2024-11-21 17:23:21,295 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Selected feedbacks: [{'feedback_type': 'Tips & Advice', 'search_query': 'strategies for personal growth'}, {'feedback_type': 'Encouragement', 'search_query': 'motivational messages for self-improvement'}, {'feedback_type': 'Book/Podcast Recommendations', 'search_query': 'best personal growth books'}]
|
| 220 |
+
2024-11-21 17:23:21,295 [INFO] [assistant_get_feedback] [55ff3647-1694-4e78-a93a-091f3e099ced]: Searched feedbacks: ['Feedback Type: Tips & Advice, Feedback On: strategies for personal growth', 'Feedback Type: Encouragement, Feedback On: motivational messages for self-improvement', 'Feedback Type: Book/Podcast Recommendations, Feedback On: best personal growth books']
|
| 221 |
+
2024-11-21 17:23:34,002 [INFO] [assistant_submit_tools] [55ff3647-1694-4e78-a93a-091f3e099ced]: Tool outputs submitted successfully
|
| 222 |
+
2024-11-21 17:23:37,668 [INFO] [user_change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Date Updated: 24/11/2024 Sun 10:00:00
|
| 223 |
+
2024-11-21 17:23:37,668 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Date changed successfully for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 224 |
+
2024-11-21 17:23:37,668 [INFO] [upload_mementos_to_db] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploading mementos to DB for user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 225 |
+
2024-11-21 17:23:37,836 [INFO] [upload_mementos_to_db] [55ff3647-1694-4e78-a93a-091f3e099ced]: Successfully uploaded mementos for user 55ff3647-1694-4e78-a93a-091f3e099ced to DB
|
| 226 |
+
2024-11-21 17:23:37,840 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploaded mementos to DB for user: 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 227 |
+
2024-11-21 17:23:37,840 [INFO] [update_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: Updating user 55ff3647-1694-4e78-a93a-091f3e099ced
|
| 228 |
+
2024-11-21 17:23:37,840 [INFO] [upload_file_to_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: Uploading file 55ff3647-1694-4e78-a93a-091f3e099ced.pkl to S3
|
| 229 |
+
2024-11-21 17:23:39,104 [INFO] [upload_file_to_s3] [55ff3647-1694-4e78-a93a-091f3e099ced]: File 55ff3647-1694-4e78-a93a-091f3e099ced.pkl uploaded successfully to S3
|
| 230 |
+
2024-11-21 17:23:39,104 [INFO] [update_user] [55ff3647-1694-4e78-a93a-091f3e099ced]: User 55ff3647-1694-4e78-a93a-091f3e099ced updated successfully in S3
|
| 231 |
+
2024-11-21 17:23:39,104 [INFO] [/change_date] [55ff3647-1694-4e78-a93a-091f3e099ced]: Request: POST Status: 200
|
app/logs/users/no-user.log
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2024-11-21 17:02:39,266 [INFO] [/docs] [None]: Request: GET Status: 200
|
| 2 |
+
2024-11-21 17:02:39,357 [INFO] [/openapi.json] [None]: Request: GET Status: 200
|
| 3 |
+
2024-11-21 17:18:43,821 [INFO] [/docs] [None]: Request: GET Status: 200
|
| 4 |
+
2024-11-21 17:18:43,923 [INFO] [/openapi.json] [None]: Request: GET Status: 200
|
app/main.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
from fastapi import FastAPI, HTTPException, Security, Query, status
|
| 2 |
from fastapi.security import APIKeyHeader
|
| 3 |
from pydantic import BaseModel
|
| 4 |
from uuid import UUID
|
|
@@ -8,16 +8,185 @@ import json
|
|
| 8 |
import regex as re
|
| 9 |
from datetime import datetime
|
| 10 |
from app.user import User
|
| 11 |
-
from typing import List, Optional
|
| 12 |
from openai import OpenAI
|
| 13 |
import psycopg2
|
| 14 |
from psycopg2 import sql
|
| 15 |
import os
|
| 16 |
from app.utils import get_api_key, get_user_info, update_user, upload_file_to_s3, get_user, upload_mementos_to_db
|
| 17 |
from dotenv import load_dotenv
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
load_dotenv()
|
| 20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
# OpenAI Client
|
| 22 |
openai_assistant = "asst_SI8I6oLdqPAQTAiUL3tTO8E4"
|
| 23 |
|
|
@@ -26,14 +195,7 @@ openai_assistant = "asst_SI8I6oLdqPAQTAiUL3tTO8E4"
|
|
| 26 |
|
| 27 |
# FastAPI App
|
| 28 |
app = FastAPI(title="Ourcoach AI API", description="A FastAPI app for ourcoach's chatbot", version="0.1.0")
|
| 29 |
-
|
| 30 |
-
# create required folders user/data and user/to_upload and mementos/to_upload only if they dont exist
|
| 31 |
-
if not os.path.exists(os.path.join('users', 'data')):
|
| 32 |
-
os.makedirs(os.path.join('users', 'data'))
|
| 33 |
-
if not os.path.exists(os.path.join('users', 'to_upload')):
|
| 34 |
-
os.makedirs(os.path.join('users', 'to_upload'))
|
| 35 |
-
if not os.path.exists(os.path.join('mementos', 'to_upload')):
|
| 36 |
-
os.makedirs(os.path.join('mementos', 'to_upload'))
|
| 37 |
|
| 38 |
# Pydantic Models
|
| 39 |
class CreateUserItem(BaseModel):
|
|
@@ -55,19 +217,24 @@ class ErrorResponse(BaseModel):
|
|
| 55 |
|
| 56 |
@app.get("/ok")
|
| 57 |
def ok_endpoint():
|
|
|
|
| 58 |
return {"message": "ok"}
|
| 59 |
|
| 60 |
@app.get("/get_user")
|
| 61 |
def get_user_by_id(user_id: str, api_key: str = Security(get_api_key)):
|
|
|
|
| 62 |
try:
|
| 63 |
user = get_user(user_id)
|
|
|
|
| 64 |
return {"user_info": user.user_info, "user_messages": user.get_messages()}
|
| 65 |
except LookupError:
|
|
|
|
| 66 |
raise HTTPException(
|
| 67 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 68 |
detail=f"User with ID {user_id} not found"
|
| 69 |
)
|
| 70 |
except Exception as e:
|
|
|
|
| 71 |
raise HTTPException(
|
| 72 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 73 |
detail=str(e)
|
|
@@ -75,36 +242,59 @@ def get_user_by_id(user_id: str, api_key: str = Security(get_api_key)):
|
|
| 75 |
|
| 76 |
@app.post("/create_user")
|
| 77 |
def create_user(request: CreateUserItem, api_key: str = Security(get_api_key)):
|
|
|
|
| 78 |
try:
|
| 79 |
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
|
| 80 |
|
| 81 |
# check if user exists by looking for pickle file in users/data
|
| 82 |
if os.path.exists(f'users/data/{request.user_id}.pkl'):
|
|
|
|
| 83 |
return {"message": f"[OK] User already exists: {request.user_id}"}
|
| 84 |
|
| 85 |
user_info, matters_most = get_user_info(request.user_id)
|
| 86 |
if not user_info:
|
|
|
|
| 87 |
raise HTTPException(
|
| 88 |
status_code=status.HTTP_400_BAD_REQUEST,
|
| 89 |
detail="Could not fetch user information from DB"
|
| 90 |
)
|
| 91 |
|
| 92 |
user = User(request.user_id, user_info, client, openai_assistant, matters_most)
|
| 93 |
-
user.save_user()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
|
| 95 |
# upload user pickle file to s3 bucket
|
| 96 |
filename = f'{user.user_id}.pkl'
|
| 97 |
upload = upload_file_to_s3(filename)
|
| 98 |
|
| 99 |
if upload == True:
|
| 100 |
-
|
|
|
|
| 101 |
else:
|
|
|
|
| 102 |
raise HTTPException(
|
| 103 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 104 |
detail="Failed to upload user pickle to S3"
|
| 105 |
)
|
| 106 |
|
| 107 |
except Exception as e:
|
|
|
|
| 108 |
raise HTTPException(
|
| 109 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 110 |
detail=str(e)
|
|
@@ -112,62 +302,83 @@ def create_user(request: CreateUserItem, api_key: str = Security(get_api_key)):
|
|
| 112 |
|
| 113 |
@app.post("/chat")
|
| 114 |
def chat(request: ChatItem, api_key: str = Security(get_api_key)):
|
|
|
|
| 115 |
try:
|
| 116 |
# get user
|
| 117 |
user = get_user(request.user_id)
|
| 118 |
response = user.send_message(request.message)
|
|
|
|
| 119 |
return {"response": response}
|
| 120 |
except LookupError:
|
|
|
|
| 121 |
raise HTTPException(
|
| 122 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 123 |
detail=f"User with ID {request.user_id} not found"
|
| 124 |
)
|
| 125 |
except Exception as e:
|
|
|
|
| 126 |
raise HTTPException(
|
| 127 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 128 |
detail=str(e)
|
| 129 |
)
|
| 130 |
|
| 131 |
@app.post("/change_date")
|
| 132 |
-
# request = {"date": "2022-01-01 Wed 10:00:00"} i.e. %Y-%m-%d %a %H:%M:%S
|
| 133 |
-
# NOTE: currently this is done for ALL users in this single endpoint which is fine for maybe < 1k users
|
| 134 |
-
# NOTE: this should be done for each user individually by accepting a user_id,
|
| 135 |
-
# this is so that the backend can handle batching logic for us, allowing us to scale >1k users
|
| 136 |
def change_date(request: ChangeDateItem, api_key: str = Security(get_api_key)):
|
|
|
|
|
|
|
| 137 |
try:
|
| 138 |
user_id = request.user_id
|
| 139 |
|
| 140 |
-
# Change the users date and get good morning response message
|
| 141 |
user = get_user(user_id)
|
| 142 |
response = user.change_date(request.date)
|
| 143 |
response['user_id'] = user_id
|
| 144 |
|
| 145 |
-
|
|
|
|
| 146 |
|
| 147 |
# Push users mementos to DB
|
| 148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
# Update user
|
| 151 |
update = update_user(user)
|
| 152 |
if not update:
|
|
|
|
| 153 |
raise HTTPException(
|
| 154 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 155 |
-
detail=f"Failed to update user
|
| 156 |
)
|
| 157 |
|
| 158 |
return {"response": response}
|
| 159 |
|
| 160 |
except ValueError as e:
|
|
|
|
| 161 |
raise HTTPException(
|
| 162 |
status_code=status.HTTP_400_BAD_REQUEST,
|
| 163 |
detail=str(e)
|
| 164 |
)
|
| 165 |
except LookupError:
|
|
|
|
| 166 |
raise HTTPException(
|
| 167 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 168 |
detail=f"User with ID {request.user_id} not found"
|
| 169 |
)
|
| 170 |
except Exception as e:
|
|
|
|
| 171 |
raise HTTPException(
|
| 172 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 173 |
detail=str(e)
|
|
@@ -175,18 +386,24 @@ def change_date(request: ChangeDateItem, api_key: str = Security(get_api_key)):
|
|
| 175 |
|
| 176 |
@app.post("/reset_user")
|
| 177 |
def reset_user_messages(request: CreateUserItem, api_key: str = Security(get_api_key)):
|
|
|
|
| 178 |
try:
|
| 179 |
-
# get user
|
| 180 |
user = get_user(request.user_id)
|
| 181 |
user.reset()
|
|
|
|
|
|
|
| 182 |
update_user(user)
|
|
|
|
|
|
|
| 183 |
return {"response": "ok"}
|
| 184 |
except LookupError:
|
|
|
|
| 185 |
raise HTTPException(
|
| 186 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 187 |
detail=f"User with ID {request.user_id} not found"
|
| 188 |
)
|
| 189 |
except Exception as e:
|
|
|
|
| 190 |
raise HTTPException(
|
| 191 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 192 |
detail=str(e)
|
|
|
|
| 1 |
+
from fastapi import FastAPI, HTTPException, Security, Query, status, Request
|
| 2 |
from fastapi.security import APIKeyHeader
|
| 3 |
from pydantic import BaseModel
|
| 4 |
from uuid import UUID
|
|
|
|
| 8 |
import regex as re
|
| 9 |
from datetime import datetime
|
| 10 |
from app.user import User
|
| 11 |
+
from typing import List, Optional, Callable
|
| 12 |
from openai import OpenAI
|
| 13 |
import psycopg2
|
| 14 |
from psycopg2 import sql
|
| 15 |
import os
|
| 16 |
from app.utils import get_api_key, get_user_info, update_user, upload_file_to_s3, get_user, upload_mementos_to_db
|
| 17 |
from dotenv import load_dotenv
|
| 18 |
+
import logging.config
|
| 19 |
+
import time
|
| 20 |
+
from starlette.middleware.base import BaseHTTPMiddleware
|
| 21 |
+
import sys
|
| 22 |
|
| 23 |
load_dotenv()
|
| 24 |
|
| 25 |
+
# Create required folders
|
| 26 |
+
os.makedirs('logs', exist_ok=True)
|
| 27 |
+
os.makedirs(os.path.join('logs', 'users'), exist_ok=True)
|
| 28 |
+
if not os.path.exists(os.path.join('users', 'data')):
|
| 29 |
+
os.makedirs(os.path.join('users', 'data'))
|
| 30 |
+
if not os.path.exists(os.path.join('users', 'to_upload')):
|
| 31 |
+
os.makedirs(os.path.join('users', 'to_upload'))
|
| 32 |
+
if not os.path.exists(os.path.join('mementos', 'to_upload')):
|
| 33 |
+
os.makedirs(os.path.join('mementos', 'to_upload'))
|
| 34 |
+
|
| 35 |
+
# Custom filter for user-specific logs
|
| 36 |
+
class UserFilter(logging.Filter):
|
| 37 |
+
def filter(self, record):
|
| 38 |
+
return hasattr(record, 'user_id') and record.user_id != "no-user"
|
| 39 |
+
|
| 40 |
+
class NoUserFilter(logging.Filter):
|
| 41 |
+
def filter(self, record):
|
| 42 |
+
return not (hasattr(record, 'user_id') and record.user_id != "no-user")
|
| 43 |
+
|
| 44 |
+
class UserLogHandler(logging.Handler):
|
| 45 |
+
def __init__(self, **kwargs):
|
| 46 |
+
super().__init__()
|
| 47 |
+
self.base_path = kwargs.get('base_path', 'logs/users')
|
| 48 |
+
self.maxBytes = kwargs.get('maxBytes', 10485760)
|
| 49 |
+
self.backupCount = kwargs.get('backupCount', 3)
|
| 50 |
+
self.handlers = {}
|
| 51 |
+
|
| 52 |
+
# Ensure base path exists
|
| 53 |
+
os.makedirs(self.base_path, exist_ok=True)
|
| 54 |
+
|
| 55 |
+
def emit(self, record):
|
| 56 |
+
if hasattr(record, 'user_id') and record.user_id != "no-user":
|
| 57 |
+
# Remove brackets from filename
|
| 58 |
+
if record.user_id:
|
| 59 |
+
user_id = record.user_id.strip('[]').strip()
|
| 60 |
+
else:
|
| 61 |
+
user_id = "no-user"
|
| 62 |
+
if user_id not in self.handlers:
|
| 63 |
+
handler = logging.handlers.RotatingFileHandler(
|
| 64 |
+
filename=os.path.join(self.base_path, f'{user_id}.log'),
|
| 65 |
+
maxBytes=self.maxBytes,
|
| 66 |
+
backupCount=self.backupCount,
|
| 67 |
+
encoding='utf-8'
|
| 68 |
+
)
|
| 69 |
+
formatter = logging.Formatter('%(asctime)s [%(levelname)s] [%(endpoint)s] [%(user_id)s]: %(message)s')
|
| 70 |
+
handler.setFormatter(formatter)
|
| 71 |
+
self.handlers[user_id] = handler
|
| 72 |
+
try:
|
| 73 |
+
self.handlers[user_id].emit(record)
|
| 74 |
+
except Exception:
|
| 75 |
+
self.handleError(record)
|
| 76 |
+
|
| 77 |
+
class ConditionalFormatter(logging.Formatter):
|
| 78 |
+
def format(self, record):
|
| 79 |
+
format_string = '%(asctime)s [%(levelname)s]'
|
| 80 |
+
if getattr(record, 'endpoint', None):
|
| 81 |
+
format_string += ' [%(endpoint)s]'
|
| 82 |
+
if getattr(record, 'user_id', None):
|
| 83 |
+
format_string += ' [%(user_id)s]'
|
| 84 |
+
if getattr(record, 'duration', None):
|
| 85 |
+
format_string += ' [Duration: %(duration).3fs]'
|
| 86 |
+
format_string += ': %(message)s'
|
| 87 |
+
self._style._fmt = format_string
|
| 88 |
+
return super().format(record)
|
| 89 |
+
|
| 90 |
+
# Configure logging
|
| 91 |
+
logging_config = {
|
| 92 |
+
'version': 1,
|
| 93 |
+
'disable_existing_loggers': False,
|
| 94 |
+
'formatters': {
|
| 95 |
+
'conditional': {
|
| 96 |
+
'()': ConditionalFormatter,
|
| 97 |
+
'datefmt': '%Y-%m-%d %H:%M:%S',
|
| 98 |
+
},
|
| 99 |
+
},
|
| 100 |
+
'filters': {
|
| 101 |
+
'userfilter': {
|
| 102 |
+
'()': UserFilter
|
| 103 |
+
},
|
| 104 |
+
'nouserfilter': {
|
| 105 |
+
'()': NoUserFilter
|
| 106 |
+
}
|
| 107 |
+
},
|
| 108 |
+
'handlers': {
|
| 109 |
+
'default': {
|
| 110 |
+
'level': 'INFO',
|
| 111 |
+
'formatter': 'conditional',
|
| 112 |
+
'class': 'logging.StreamHandler',
|
| 113 |
+
'stream': sys.stdout, # Use stdout instead of stderr
|
| 114 |
+
'filters': ['nouserfilter']
|
| 115 |
+
},
|
| 116 |
+
'file': {
|
| 117 |
+
'level': 'INFO',
|
| 118 |
+
'formatter': 'conditional',
|
| 119 |
+
'class': 'logging.handlers.RotatingFileHandler',
|
| 120 |
+
'filename': 'logs/app.log',
|
| 121 |
+
'maxBytes': 10485760, # 10MB
|
| 122 |
+
'backupCount': 5,
|
| 123 |
+
'encoding': 'utf-8', # Add UTF-8 encoding
|
| 124 |
+
'filters': ['nouserfilter']
|
| 125 |
+
},
|
| 126 |
+
'userfile': {
|
| 127 |
+
'level': 'INFO',
|
| 128 |
+
'formatter': 'conditional',
|
| 129 |
+
'()': UserLogHandler, # Changed from 'class' to '()'
|
| 130 |
+
'base_path': 'logs/users',
|
| 131 |
+
'maxBytes': 10485760,
|
| 132 |
+
'backupCount': 3,
|
| 133 |
+
'filters': ['userfilter']
|
| 134 |
+
}
|
| 135 |
+
},
|
| 136 |
+
'loggers': {
|
| 137 |
+
'': { # root logger
|
| 138 |
+
'handlers': ['default', 'file', 'userfile'],
|
| 139 |
+
'level': 'INFO',
|
| 140 |
+
'propagate': True
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
logging.config.dictConfig(logging_config)
|
| 146 |
+
logger = logging.getLogger(__name__)
|
| 147 |
+
|
| 148 |
+
# Request logging middleware
|
| 149 |
+
class LoggingMiddleware(BaseHTTPMiddleware):
|
| 150 |
+
async def dispatch(self, request: Request, call_next: Callable):
|
| 151 |
+
start_time = time.time()
|
| 152 |
+
user_id = None
|
| 153 |
+
if "user_id" in request.query_params:
|
| 154 |
+
user_id = request.query_params["user_id"]
|
| 155 |
+
elif request.method == "POST":
|
| 156 |
+
try:
|
| 157 |
+
body = await request.json()
|
| 158 |
+
user_id = body.get("user_id")
|
| 159 |
+
except:
|
| 160 |
+
pass
|
| 161 |
+
|
| 162 |
+
endpoint = request.url.path
|
| 163 |
+
|
| 164 |
+
try:
|
| 165 |
+
response = await call_next(request)
|
| 166 |
+
duration = time.time() - start_time
|
| 167 |
+
extra = {
|
| 168 |
+
"user_id": user_id,
|
| 169 |
+
"endpoint": endpoint,
|
| 170 |
+
"duration": duration,
|
| 171 |
+
}
|
| 172 |
+
logger.info(
|
| 173 |
+
f"Request: {request.method} Status: {response.status_code}",
|
| 174 |
+
extra=extra
|
| 175 |
+
)
|
| 176 |
+
return response
|
| 177 |
+
except Exception as e:
|
| 178 |
+
duration = time.time() - start_time
|
| 179 |
+
extra = {
|
| 180 |
+
"user_id": user_id,
|
| 181 |
+
"endpoint": endpoint,
|
| 182 |
+
"duration": duration,
|
| 183 |
+
}
|
| 184 |
+
logger.error(
|
| 185 |
+
f"Request failed: {request.method} Error: {str(e)}",
|
| 186 |
+
extra=extra
|
| 187 |
+
)
|
| 188 |
+
raise
|
| 189 |
+
|
| 190 |
# OpenAI Client
|
| 191 |
openai_assistant = "asst_SI8I6oLdqPAQTAiUL3tTO8E4"
|
| 192 |
|
|
|
|
| 195 |
|
| 196 |
# FastAPI App
|
| 197 |
app = FastAPI(title="Ourcoach AI API", description="A FastAPI app for ourcoach's chatbot", version="0.1.0")
|
| 198 |
+
app.add_middleware(LoggingMiddleware)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
|
| 200 |
# Pydantic Models
|
| 201 |
class CreateUserItem(BaseModel):
|
|
|
|
| 217 |
|
| 218 |
@app.get("/ok")
|
| 219 |
def ok_endpoint():
|
| 220 |
+
logger.info("Health check endpoint called", extra={"endpoint": "/ok"})
|
| 221 |
return {"message": "ok"}
|
| 222 |
|
| 223 |
@app.get("/get_user")
|
| 224 |
def get_user_by_id(user_id: str, api_key: str = Security(get_api_key)):
|
| 225 |
+
logger.info("Getting user", extra={"user_id": user_id, "endpoint": "/get_user"})
|
| 226 |
try:
|
| 227 |
user = get_user(user_id)
|
| 228 |
+
logger.info("Successfully retrieved user", extra={"user_id": user_id, "endpoint": "/get_user"})
|
| 229 |
return {"user_info": user.user_info, "user_messages": user.get_messages()}
|
| 230 |
except LookupError:
|
| 231 |
+
logger.error("User not found", extra={"user_id": user_id, "endpoint": "/get_user"})
|
| 232 |
raise HTTPException(
|
| 233 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 234 |
detail=f"User with ID {user_id} not found"
|
| 235 |
)
|
| 236 |
except Exception as e:
|
| 237 |
+
logger.error(f"Error getting user: {str(e)}", extra={"user_id": user_id, "endpoint": "/get_user"}, exc_info=True)
|
| 238 |
raise HTTPException(
|
| 239 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 240 |
detail=str(e)
|
|
|
|
| 242 |
|
| 243 |
@app.post("/create_user")
|
| 244 |
def create_user(request: CreateUserItem, api_key: str = Security(get_api_key)):
|
| 245 |
+
logger.info("Creating new user", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 246 |
try:
|
| 247 |
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
|
| 248 |
|
| 249 |
# check if user exists by looking for pickle file in users/data
|
| 250 |
if os.path.exists(f'users/data/{request.user_id}.pkl'):
|
| 251 |
+
logger.info(f"User already exists: {request.user_id}", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 252 |
return {"message": f"[OK] User already exists: {request.user_id}"}
|
| 253 |
|
| 254 |
user_info, matters_most = get_user_info(request.user_id)
|
| 255 |
if not user_info:
|
| 256 |
+
logger.error(f"Could not fetch user information from DB {request.user_id}", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 257 |
raise HTTPException(
|
| 258 |
status_code=status.HTTP_400_BAD_REQUEST,
|
| 259 |
detail="Could not fetch user information from DB"
|
| 260 |
)
|
| 261 |
|
| 262 |
user = User(request.user_id, user_info, client, openai_assistant, matters_most)
|
| 263 |
+
save = user.save_user()
|
| 264 |
+
|
| 265 |
+
if save:
|
| 266 |
+
logger.info(f"Created pickle file for user", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 267 |
+
else:
|
| 268 |
+
logger.error(f"Failed to create (user.save_user()) pickle file", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 269 |
+
raise HTTPException(
|
| 270 |
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 271 |
+
detail="Failed to create user pickle file"
|
| 272 |
+
)
|
| 273 |
+
|
| 274 |
+
# create memento folder for user
|
| 275 |
+
folder_path = os.path.join("mementos", "to_upload", request.user_id)
|
| 276 |
+
|
| 277 |
+
# create folder if not exists
|
| 278 |
+
os.makedirs(folder_path, exist_ok=True)
|
| 279 |
+
logger.info(f"Created temp memento folder for user", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 280 |
+
|
| 281 |
|
| 282 |
# upload user pickle file to s3 bucket
|
| 283 |
filename = f'{user.user_id}.pkl'
|
| 284 |
upload = upload_file_to_s3(filename)
|
| 285 |
|
| 286 |
if upload == True:
|
| 287 |
+
logger.info(f"Successfully created user", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 288 |
+
return {"message": f"[OK] User created: {user.user_id}"}
|
| 289 |
else:
|
| 290 |
+
logger.error(f"Failed to upload user pickle to S3", extra={"user_id": request.user_id, "endpoint": "/create_user"})
|
| 291 |
raise HTTPException(
|
| 292 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 293 |
detail="Failed to upload user pickle to S3"
|
| 294 |
)
|
| 295 |
|
| 296 |
except Exception as e:
|
| 297 |
+
logger.error(f"Failed to create user: {str(e)}", extra={"user_id": request.user_id, "endpoint": "/create_user"}, exc_info=True)
|
| 298 |
raise HTTPException(
|
| 299 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 300 |
detail=str(e)
|
|
|
|
| 302 |
|
| 303 |
@app.post("/chat")
|
| 304 |
def chat(request: ChatItem, api_key: str = Security(get_api_key)):
|
| 305 |
+
logger.info("Processing chat request", extra={"user_id": request.user_id, "endpoint": "/chat"})
|
| 306 |
try:
|
| 307 |
# get user
|
| 308 |
user = get_user(request.user_id)
|
| 309 |
response = user.send_message(request.message)
|
| 310 |
+
logger.info(f"Assistant: {response['content']}", extra={"user_id": request.user_id, "endpoint": "/chat"})
|
| 311 |
return {"response": response}
|
| 312 |
except LookupError:
|
| 313 |
+
logger.error(f"User not found for chat: {request.user_id}", extra={"user_id": request.user_id, "endpoint": "/chat"})
|
| 314 |
raise HTTPException(
|
| 315 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 316 |
detail=f"User with ID {request.user_id} not found"
|
| 317 |
)
|
| 318 |
except Exception as e:
|
| 319 |
+
logger.error(f"Chat error for user {request.user_id}: {str(e)}", extra={"user_id": request.user_id, "endpoint": "/chat"}, exc_info=True)
|
| 320 |
raise HTTPException(
|
| 321 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 322 |
detail=str(e)
|
| 323 |
)
|
| 324 |
|
| 325 |
@app.post("/change_date")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
def change_date(request: ChangeDateItem, api_key: str = Security(get_api_key)):
|
| 327 |
+
logger.info(f"Processing date change request, new date: {request.date}",
|
| 328 |
+
extra={"user_id": request.user_id, "endpoint": "/change_date"})
|
| 329 |
try:
|
| 330 |
user_id = request.user_id
|
| 331 |
|
|
|
|
| 332 |
user = get_user(user_id)
|
| 333 |
response = user.change_date(request.date)
|
| 334 |
response['user_id'] = user_id
|
| 335 |
|
| 336 |
+
logger.info(f"Date changed successfully for user: {user_id}", extra={"user_id": user_id, "endpoint": "/change_date"})
|
| 337 |
+
logger.debug(f"Change date response: {response}", extra={"user_id": user_id, "endpoint": "/change_date"})
|
| 338 |
|
| 339 |
# Push users mementos to DB
|
| 340 |
+
try:
|
| 341 |
+
upload = upload_mementos_to_db(user_id)
|
| 342 |
+
if upload:
|
| 343 |
+
logger.info(f"Uploaded mementos to DB for user: {user_id}", extra={"user_id": user_id, "endpoint": "/change_date"})
|
| 344 |
+
else:
|
| 345 |
+
logger.error(f"Failed to upload mementos to DB for user: {user_id}", extra={"user_id": user_id, "endpoint": "/change_date"})
|
| 346 |
+
raise HTTPException(
|
| 347 |
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 348 |
+
detail=f"Failed to upload mementos to DB for user: {user_id}"
|
| 349 |
+
)
|
| 350 |
+
except ConnectionError as e:
|
| 351 |
+
logger.error(f"Failed to connect to DB for user: {user_id}", extra={"user_id": user_id, "endpoint": "/change_date"})
|
| 352 |
+
raise HTTPException(
|
| 353 |
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 354 |
+
detail=f"Failed to connect to DB for user: {user_id}"
|
| 355 |
+
)
|
| 356 |
|
| 357 |
# Update user
|
| 358 |
update = update_user(user)
|
| 359 |
if not update:
|
| 360 |
+
logger.error(f"Failed to update user pickle in S3: {user_id}", extra={"user_id": user_id, "endpoint": "/change_date"})
|
| 361 |
raise HTTPException(
|
| 362 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 363 |
+
detail=f"Failed to update user pickle in S3 {user_id}"
|
| 364 |
)
|
| 365 |
|
| 366 |
return {"response": response}
|
| 367 |
|
| 368 |
except ValueError as e:
|
| 369 |
+
logger.error(f"Invalid date format for user {request.user_id}: {str(e)}", extra={"user_id": request.user_id, "endpoint": "/change_date"})
|
| 370 |
raise HTTPException(
|
| 371 |
status_code=status.HTTP_400_BAD_REQUEST,
|
| 372 |
detail=str(e)
|
| 373 |
)
|
| 374 |
except LookupError:
|
| 375 |
+
logger.error(f"User not found for date change: {request.user_id}", extra={"user_id": request.user_id, "endpoint": "/change_date"})
|
| 376 |
raise HTTPException(
|
| 377 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 378 |
detail=f"User with ID {request.user_id} not found"
|
| 379 |
)
|
| 380 |
except Exception as e:
|
| 381 |
+
logger.error(f"Error changing date for user {request.user_id}: {str(e)}", extra={"user_id": request.user_id, "endpoint": "/change_date"}, exc_info=True)
|
| 382 |
raise HTTPException(
|
| 383 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 384 |
detail=str(e)
|
|
|
|
| 386 |
|
| 387 |
@app.post("/reset_user")
|
| 388 |
def reset_user_messages(request: CreateUserItem, api_key: str = Security(get_api_key)):
|
| 389 |
+
logger.info("Resetting messages", extra={"user_id": request.user_id, "endpoint": "/reset_user"})
|
| 390 |
try:
|
|
|
|
| 391 |
user = get_user(request.user_id)
|
| 392 |
user.reset()
|
| 393 |
+
logger.info(f"Successfully reset messages for user: {request.user_id}", extra={"user_id": request.user_id, "endpoint": "/reset_user"})
|
| 394 |
+
|
| 395 |
update_user(user)
|
| 396 |
+
logger.info(f"Successfully updated user pickle: {request.user_id}", extra={"user_id": request.user_id, "endpoint": "/reset_user"})
|
| 397 |
+
|
| 398 |
return {"response": "ok"}
|
| 399 |
except LookupError:
|
| 400 |
+
logger.error(f"User not found for reset: {request.user_id}", extra={"user_id": request.user_id, "endpoint": "/reset_user"})
|
| 401 |
raise HTTPException(
|
| 402 |
status_code=status.HTTP_404_NOT_FOUND,
|
| 403 |
detail=f"User with ID {request.user_id} not found"
|
| 404 |
)
|
| 405 |
except Exception as e:
|
| 406 |
+
logger.error(f"Error resetting user {request.user_id}: {str(e)}", extra={"user_id": request.user_id, "endpoint": "/reset_user"}, exc_info=True)
|
| 407 |
raise HTTPException(
|
| 408 |
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 409 |
detail=str(e)
|
app/user.py
CHANGED
|
@@ -8,6 +8,9 @@ from app.assistants import Assistant
|
|
| 8 |
import glob
|
| 9 |
import dill as pickle
|
| 10 |
import random
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
def get_current_datetime():
|
| 13 |
return datetime.now()
|
|
@@ -22,8 +25,7 @@ class ConversationManager:
|
|
| 22 |
|
| 23 |
self.current_thread = self.create_thread()
|
| 24 |
|
| 25 |
-
|
| 26 |
-
print("[Init State]:", self.state)
|
| 27 |
|
| 28 |
def __getstate__(self):
|
| 29 |
state = self.__dict__.copy()
|
|
@@ -128,9 +130,9 @@ class User:
|
|
| 128 |
self.client = client
|
| 129 |
self.asst_id = asst_id
|
| 130 |
self.user_info = user_info
|
| 131 |
-
self.matters_most = CircularQueue(matters_most)
|
| 132 |
self.matters_most.next() # skip the first topic since the first reflection (right after intro) will ask it
|
| 133 |
-
|
| 134 |
# self.events = None
|
| 135 |
self.user_interaction_guidelines = self.generate_user_interaction_guidelines(user_info, client)
|
| 136 |
# self.coaching_plans = {}
|
|
@@ -181,7 +183,7 @@ class User:
|
|
| 181 |
|
| 182 |
def send_message(self, text):
|
| 183 |
response = self.conversations._run_current_thread(text)
|
| 184 |
-
|
| 185 |
return response
|
| 186 |
|
| 187 |
def get_messages(self, exclude_system_msg=True):
|
|
@@ -191,13 +193,14 @@ class User:
|
|
| 191 |
return list(filter(lambda x: not (x['content'].startswith("** It is a new day:") or x['content'].startswith("Pay attention to the current state you are in") or x['content'].startswith("Date changed to")), self.conversations._get_current_thread_history(exclude_system_msg)))
|
| 192 |
|
| 193 |
def change_date(self, date):
|
| 194 |
-
|
|
|
|
| 195 |
self.conversations.state['date'] = date
|
| 196 |
|
| 197 |
# reflection_topic = random.choice(['Career growth 💼','Health & wellness 🍎','Better relationships ❤️','Personal growth 🪴','Mental well-being 🧠'])
|
| 198 |
question_format = random.choice(['[Option 1] Likert-Scale Objective Question','[Option 2] Multiple-Choice Question','[Option 3] Yes-No Question'])
|
| 199 |
topic = self.matters_most.current()
|
| 200 |
-
|
| 201 |
|
| 202 |
response = self.conversations._send_hidden_message(f"""** It is a new day: {date} **
|
| 203 |
Additional System Instruction:
|
|
@@ -222,7 +225,7 @@ class User:
|
|
| 222 |
**<question>**
|
| 223 |
“””
|
| 224 |
""")
|
| 225 |
-
|
| 226 |
return response
|
| 227 |
|
| 228 |
def __hash__(self) -> int:
|
|
@@ -292,13 +295,14 @@ Use bullet points or numbered lists where appropriate to enhance readability."""
|
|
| 292 |
return response.choices[0].message.content
|
| 293 |
|
| 294 |
def infer_memento_follow_ups(self):
|
| 295 |
-
mementos_path =
|
|
|
|
| 296 |
|
| 297 |
for file_path in glob.glob(mementos_path):
|
| 298 |
with open(file_path, 'r+') as file:
|
| 299 |
data = json.load(file)
|
| 300 |
infered_follow_up = self._infer_follow_ups(data['created'], data['context'])
|
| 301 |
-
|
| 302 |
data['follow_up_on'] = infered_follow_up
|
| 303 |
file.seek(0)
|
| 304 |
json.dump(data, file, indent=4)
|
|
@@ -322,16 +326,19 @@ Use bullet points or numbered lists where appropriate to enhance readability."""
|
|
| 322 |
|
| 323 |
def save_user(self):
|
| 324 |
# Construct the file path dynamically for cross-platform compatibility
|
| 325 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
|
| 327 |
-
# Ensure the directory exists
|
| 328 |
-
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
| 329 |
-
|
| 330 |
-
# Save the user object as a pickle file
|
| 331 |
-
with open(file_path, 'wb') as file:
|
| 332 |
-
pickle.dump(self, file)
|
| 333 |
-
print(f"User object saved to {file_path}")
|
| 334 |
-
|
| 335 |
@staticmethod
|
| 336 |
def load_user(user_id, client):
|
| 337 |
# Construct the file path dynamically for cross-platform compatibility
|
|
@@ -346,9 +353,10 @@ Use bullet points or numbered lists where appropriate to enhance readability."""
|
|
| 346 |
|
| 347 |
|
| 348 |
class CircularQueue:
|
| 349 |
-
def __init__(self, array):
|
| 350 |
if not array:
|
| 351 |
raise ValueError("Array cannot be empty")
|
|
|
|
| 352 |
self.array = array
|
| 353 |
self.size = len(array)
|
| 354 |
self.index = 0 # Tracks the current position in the array
|
|
@@ -356,7 +364,7 @@ class CircularQueue:
|
|
| 356 |
def next(self):
|
| 357 |
# Get the next element and advance the index
|
| 358 |
element = self.array[self.index]
|
| 359 |
-
|
| 360 |
|
| 361 |
self.index = (self.index + 1) % self.size # Wrap around to 0 when the end is reached
|
| 362 |
return element
|
|
@@ -380,4 +388,4 @@ class CircularQueue:
|
|
| 380 |
f"current_index={self.index}, "
|
| 381 |
f"current_element={self.array[self.index]})"
|
| 382 |
)
|
| 383 |
-
|
|
|
|
| 8 |
import glob
|
| 9 |
import dill as pickle
|
| 10 |
import random
|
| 11 |
+
import logging
|
| 12 |
+
|
| 13 |
+
logger = logging.getLogger(__name__)
|
| 14 |
|
| 15 |
def get_current_datetime():
|
| 16 |
return datetime.now()
|
|
|
|
| 25 |
|
| 26 |
self.current_thread = self.create_thread()
|
| 27 |
|
| 28 |
+
logger.info("Initializing conversation state", extra={"user_id": self.user.user_id, "endpoint": "conversation_init"})
|
|
|
|
| 29 |
|
| 30 |
def __getstate__(self):
|
| 31 |
state = self.__dict__.copy()
|
|
|
|
| 130 |
self.client = client
|
| 131 |
self.asst_id = asst_id
|
| 132 |
self.user_info = user_info
|
| 133 |
+
self.matters_most = CircularQueue(array=matters_most, user_id=user_id)
|
| 134 |
self.matters_most.next() # skip the first topic since the first reflection (right after intro) will ask it
|
| 135 |
+
logger.info(f"Matters most topics: {matters_most}", extra={"user_id": user_id, "endpoint": "user_init"})
|
| 136 |
# self.events = None
|
| 137 |
self.user_interaction_guidelines = self.generate_user_interaction_guidelines(user_info, client)
|
| 138 |
# self.coaching_plans = {}
|
|
|
|
| 183 |
|
| 184 |
def send_message(self, text):
|
| 185 |
response = self.conversations._run_current_thread(text)
|
| 186 |
+
logger.info(f"Response: {response}", extra={"user_id": self.user_id, "endpoint": "user_send_message"})
|
| 187 |
return response
|
| 188 |
|
| 189 |
def get_messages(self, exclude_system_msg=True):
|
|
|
|
| 193 |
return list(filter(lambda x: not (x['content'].startswith("** It is a new day:") or x['content'].startswith("Pay attention to the current state you are in") or x['content'].startswith("Date changed to")), self.conversations._get_current_thread_history(exclude_system_msg)))
|
| 194 |
|
| 195 |
def change_date(self, date):
|
| 196 |
+
logger.info(f"Changing date from {self.conversations.state['date']} to {date}",
|
| 197 |
+
extra={"user_id": self.user_id, "endpoint": "user_change_date"})
|
| 198 |
self.conversations.state['date'] = date
|
| 199 |
|
| 200 |
# reflection_topic = random.choice(['Career growth 💼','Health & wellness 🍎','Better relationships ❤️','Personal growth 🪴','Mental well-being 🧠'])
|
| 201 |
question_format = random.choice(['[Option 1] Likert-Scale Objective Question','[Option 2] Multiple-Choice Question','[Option 3] Yes-No Question'])
|
| 202 |
topic = self.matters_most.current()
|
| 203 |
+
logger.info(f"Today's reflection topic is {topic}", extra={"user_id": self.user_id, "endpoint": "user_change_date"})
|
| 204 |
|
| 205 |
response = self.conversations._send_hidden_message(f"""** It is a new day: {date} **
|
| 206 |
Additional System Instruction:
|
|
|
|
| 225 |
**<question>**
|
| 226 |
“””
|
| 227 |
""")
|
| 228 |
+
logger.info(f"Date Updated: {self.conversations.state['date']}", extra={"user_id": self.user_id, "endpoint": "user_change_date"})
|
| 229 |
return response
|
| 230 |
|
| 231 |
def __hash__(self) -> int:
|
|
|
|
| 295 |
return response.choices[0].message.content
|
| 296 |
|
| 297 |
def infer_memento_follow_ups(self):
|
| 298 |
+
mementos_path = os.path.join("mementos", "to_upload", f"{self.user_id}", "*.json")
|
| 299 |
+
# mementos_path = f"mementos/to_upload/{self.user_id}/*.json"
|
| 300 |
|
| 301 |
for file_path in glob.glob(mementos_path):
|
| 302 |
with open(file_path, 'r+') as file:
|
| 303 |
data = json.load(file)
|
| 304 |
infered_follow_up = self._infer_follow_ups(data['created'], data['context'])
|
| 305 |
+
logger.info(f"[Infered Follow Up]: {infered_follow_up}", extra={"user_id": self.user_id, "endpoint": "infer_memento_follow_ups"})
|
| 306 |
data['follow_up_on'] = infered_follow_up
|
| 307 |
file.seek(0)
|
| 308 |
json.dump(data, file, indent=4)
|
|
|
|
| 326 |
|
| 327 |
def save_user(self):
|
| 328 |
# Construct the file path dynamically for cross-platform compatibility
|
| 329 |
+
try:
|
| 330 |
+
file_path = os.path.join("users", "to_upload", f"{self.user_id}.pkl")
|
| 331 |
+
|
| 332 |
+
# Ensure the directory exists
|
| 333 |
+
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
| 334 |
+
|
| 335 |
+
# Save the user object as a pickle file
|
| 336 |
+
with open(file_path, 'wb') as file:
|
| 337 |
+
pickle.dump(self, file)
|
| 338 |
+
return True
|
| 339 |
+
except Exception as e:
|
| 340 |
+
return False
|
| 341 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
@staticmethod
|
| 343 |
def load_user(user_id, client):
|
| 344 |
# Construct the file path dynamically for cross-platform compatibility
|
|
|
|
| 353 |
|
| 354 |
|
| 355 |
class CircularQueue:
|
| 356 |
+
def __init__(self, array, user_id):
|
| 357 |
if not array:
|
| 358 |
raise ValueError("Array cannot be empty")
|
| 359 |
+
self.user_id = user_id
|
| 360 |
self.array = array
|
| 361 |
self.size = len(array)
|
| 362 |
self.index = 0 # Tracks the current position in the array
|
|
|
|
| 364 |
def next(self):
|
| 365 |
# Get the next element and advance the index
|
| 366 |
element = self.array[self.index]
|
| 367 |
+
logger.info(f"[Reflection Topic] [Previous]: {self.array[self.index-1] if self.index else 'None'} -> [Current]: {element}", extra={"user_id": self.user_id, "endpoint": "circular_queue_next"})
|
| 368 |
|
| 369 |
self.index = (self.index + 1) % self.size # Wrap around to 0 when the end is reached
|
| 370 |
return element
|
|
|
|
| 388 |
f"current_index={self.index}, "
|
| 389 |
f"current_element={self.array[self.index]})"
|
| 390 |
)
|
| 391 |
+
|
app/utils.py
CHANGED
|
@@ -28,33 +28,42 @@ AWS_ACCESS_KEY = os.getenv('AWS_ACCESS_KEY')
|
|
| 28 |
AWS_SECRET_KEY = os.getenv('AWS_SECRET_KEY')
|
| 29 |
REGION = os.getenv('AWS_REGION')
|
| 30 |
|
|
|
|
|
|
|
| 31 |
def force_file_move(source, destination):
|
|
|
|
|
|
|
| 32 |
try:
|
| 33 |
# Ensure the destination directory exists
|
| 34 |
os.makedirs(os.path.dirname(destination), exist_ok=True)
|
| 35 |
|
| 36 |
# Move the file, replacing if it already exists
|
| 37 |
os.replace(source, destination)
|
| 38 |
-
|
| 39 |
except FileNotFoundError:
|
| 40 |
-
|
| 41 |
except Exception as e:
|
| 42 |
-
|
| 43 |
|
| 44 |
def get_user(user_id):
|
|
|
|
|
|
|
| 45 |
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
|
| 46 |
user_file = os.path.join('users', 'data', f'{user_id}.pkl')
|
| 47 |
if os.path.exists(user_file):
|
| 48 |
user = User.load_user(user_id, client)
|
|
|
|
| 49 |
return user
|
| 50 |
else:
|
| 51 |
-
|
| 52 |
download = download_file_from_s3(f'{user_id}.pkl', 'core-ai-assets')
|
| 53 |
-
|
| 54 |
if download:
|
| 55 |
user = User.load_user(user_id, client)
|
|
|
|
| 56 |
return user
|
| 57 |
else:
|
|
|
|
| 58 |
raise LookupError(f"User [{user_id}] pickle does not exist in S3")
|
| 59 |
|
| 60 |
def get_api_key(api_key_header: str = Security(api_key_header)) -> str:
|
|
@@ -66,6 +75,8 @@ def get_api_key(api_key_header: str = Security(api_key_header)) -> str:
|
|
| 66 |
)
|
| 67 |
|
| 68 |
def get_user_info(user_id):
|
|
|
|
|
|
|
| 69 |
db_params = {
|
| 70 |
'dbname': 'ourcoach',
|
| 71 |
'user': 'ourcoach',
|
|
@@ -110,15 +121,19 @@ def get_user_info(user_id):
|
|
| 110 |
{user_data_clean.get('firstName', '')}'s most important person:
|
| 111 |
{whoImportant}
|
| 112 |
"""
|
| 113 |
-
|
| 114 |
return user_data_formatted, user_data_clean.get('mattersMost', ['', '', '', '', ''])
|
| 115 |
else:
|
|
|
|
| 116 |
return None
|
| 117 |
except psycopg2.Error as e:
|
| 118 |
-
|
| 119 |
return None
|
| 120 |
|
| 121 |
def upload_file_to_s3(filename):
|
|
|
|
|
|
|
|
|
|
| 122 |
bucket = 'core-ai-assets'
|
| 123 |
try:
|
| 124 |
if AWS_ACCESS_KEY and AWS_SECRET_KEY:
|
|
@@ -134,15 +149,20 @@ def upload_file_to_s3(filename):
|
|
| 134 |
with open(os.path.join('users', 'to_upload', filename), "rb") as f:
|
| 135 |
s3_client.upload_fileobj(f, bucket, f'staging/users/{filename}')
|
| 136 |
|
|
|
|
| 137 |
force_file_move(
|
| 138 |
os.path.join('users', 'to_upload', filename),
|
| 139 |
os.path.join('users', 'data', filename)
|
| 140 |
)
|
| 141 |
return True
|
| 142 |
except (FileNotFoundError, NoCredentialsError, PartialCredentialsError) as e:
|
| 143 |
-
|
|
|
|
| 144 |
|
| 145 |
def download_file_from_s3(filename, bucket):
|
|
|
|
|
|
|
|
|
|
| 146 |
file_path = os.path.join('users', 'data', filename)
|
| 147 |
try:
|
| 148 |
if AWS_ACCESS_KEY and AWS_SECRET_KEY:
|
|
@@ -157,23 +177,31 @@ def download_file_from_s3(filename, bucket):
|
|
| 157 |
s3_client = session.client('s3')
|
| 158 |
with open(file_path, 'wb') as f:
|
| 159 |
s3_client.download_fileobj(bucket, f"staging/users/{filename}", f)
|
|
|
|
| 160 |
return True
|
| 161 |
except Exception as e:
|
| 162 |
-
|
| 163 |
if os.path.exists(file_path):
|
| 164 |
os.remove(file_path)
|
| 165 |
return False
|
| 166 |
|
| 167 |
def update_user(user):
|
|
|
|
|
|
|
|
|
|
| 168 |
user.save_user()
|
| 169 |
filename = f'{user.user_id}.pkl'
|
| 170 |
if upload_file_to_s3(filename):
|
|
|
|
| 171 |
os.remove(os.path.join('users', 'data', filename))
|
| 172 |
return True
|
| 173 |
else:
|
|
|
|
| 174 |
return False
|
| 175 |
|
| 176 |
def upload_mementos_to_db(user_id):
|
|
|
|
|
|
|
| 177 |
# Database connection parameters
|
| 178 |
db_params = {
|
| 179 |
'dbname': 'ourcoach',
|
|
@@ -185,6 +213,7 @@ def upload_mementos_to_db(user_id):
|
|
| 185 |
|
| 186 |
# Path to the folder containing JSON files for the user
|
| 187 |
folder_path = os.path.join("mementos", "to_upload", user_id)
|
|
|
|
| 188 |
try:
|
| 189 |
with psycopg2.connect(**db_params) as conn:
|
| 190 |
with conn.cursor() as cursor:
|
|
@@ -207,7 +236,13 @@ def upload_mementos_to_db(user_id):
|
|
| 207 |
cursor.execute(insert_query, list(values))
|
| 208 |
conn.commit()
|
| 209 |
os.remove(file_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
except psycopg2.Error as e:
|
| 211 |
-
|
|
|
|
| 212 |
except Exception as e:
|
| 213 |
-
|
|
|
|
|
|
| 28 |
AWS_SECRET_KEY = os.getenv('AWS_SECRET_KEY')
|
| 29 |
REGION = os.getenv('AWS_REGION')
|
| 30 |
|
| 31 |
+
logger = logging.getLogger(__name__)
|
| 32 |
+
|
| 33 |
def force_file_move(source, destination):
|
| 34 |
+
function_name = force_file_move.__name__
|
| 35 |
+
logger.info(f"Attempting to move file from {source} to {destination}", extra={'endpoint': function_name})
|
| 36 |
try:
|
| 37 |
# Ensure the destination directory exists
|
| 38 |
os.makedirs(os.path.dirname(destination), exist_ok=True)
|
| 39 |
|
| 40 |
# Move the file, replacing if it already exists
|
| 41 |
os.replace(source, destination)
|
| 42 |
+
logger.info(f"File moved successfully: {source} -> {destination}", extra={'endpoint': function_name})
|
| 43 |
except FileNotFoundError:
|
| 44 |
+
logger.error(f"Source file not found: {source}", extra={'endpoint': function_name})
|
| 45 |
except Exception as e:
|
| 46 |
+
logger.error(f"An error occurred while moving file: {e}", extra={'endpoint': function_name})
|
| 47 |
|
| 48 |
def get_user(user_id):
|
| 49 |
+
function_name = get_user.__name__
|
| 50 |
+
logger.info(f"Fetching user {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 51 |
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
|
| 52 |
user_file = os.path.join('users', 'data', f'{user_id}.pkl')
|
| 53 |
if os.path.exists(user_file):
|
| 54 |
user = User.load_user(user_id, client)
|
| 55 |
+
logger.info(f"User {user_id} loaded successfully from local storage", extra={'user_id': user_id, 'endpoint': function_name})
|
| 56 |
return user
|
| 57 |
else:
|
| 58 |
+
logger.info(f"User {user_id} not found locally. Attempting to download from S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 59 |
download = download_file_from_s3(f'{user_id}.pkl', 'core-ai-assets')
|
| 60 |
+
logger.info(f"Download success: {download}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 61 |
if download:
|
| 62 |
user = User.load_user(user_id, client)
|
| 63 |
+
logger.info(f"User {user_id} loaded successfully from S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 64 |
return user
|
| 65 |
else:
|
| 66 |
+
logger.error(f"User {user_id} pickle does not exist in S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 67 |
raise LookupError(f"User [{user_id}] pickle does not exist in S3")
|
| 68 |
|
| 69 |
def get_api_key(api_key_header: str = Security(api_key_header)) -> str:
|
|
|
|
| 75 |
)
|
| 76 |
|
| 77 |
def get_user_info(user_id):
|
| 78 |
+
function_name = get_user_info.__name__
|
| 79 |
+
logger.info(f"Retrieving user info for {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 80 |
db_params = {
|
| 81 |
'dbname': 'ourcoach',
|
| 82 |
'user': 'ourcoach',
|
|
|
|
| 121 |
{user_data_clean.get('firstName', '')}'s most important person:
|
| 122 |
{whoImportant}
|
| 123 |
"""
|
| 124 |
+
logger.info(f"User info retrieved successfully for {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 125 |
return user_data_formatted, user_data_clean.get('mattersMost', ['', '', '', '', ''])
|
| 126 |
else:
|
| 127 |
+
logger.warning(f"No user info found for {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 128 |
return None
|
| 129 |
except psycopg2.Error as e:
|
| 130 |
+
logger.error(f"Database error while retrieving user info for {user_id}: {e}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 131 |
return None
|
| 132 |
|
| 133 |
def upload_file_to_s3(filename):
|
| 134 |
+
user_id = filename.split('.')[0]
|
| 135 |
+
function_name = upload_file_to_s3.__name__
|
| 136 |
+
logger.info(f"Uploading file {filename} to S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 137 |
bucket = 'core-ai-assets'
|
| 138 |
try:
|
| 139 |
if AWS_ACCESS_KEY and AWS_SECRET_KEY:
|
|
|
|
| 149 |
with open(os.path.join('users', 'to_upload', filename), "rb") as f:
|
| 150 |
s3_client.upload_fileobj(f, bucket, f'staging/users/{filename}')
|
| 151 |
|
| 152 |
+
logger.info(f"File {filename} uploaded successfully to S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 153 |
force_file_move(
|
| 154 |
os.path.join('users', 'to_upload', filename),
|
| 155 |
os.path.join('users', 'data', filename)
|
| 156 |
)
|
| 157 |
return True
|
| 158 |
except (FileNotFoundError, NoCredentialsError, PartialCredentialsError) as e:
|
| 159 |
+
logger.error(f"S3 upload failed for {filename}: {e}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 160 |
+
return False
|
| 161 |
|
| 162 |
def download_file_from_s3(filename, bucket):
|
| 163 |
+
user_id = filename.split('.')[0]
|
| 164 |
+
function_name = download_file_from_s3.__name__
|
| 165 |
+
logger.info(f"Downloading file {filename} from S3 bucket {bucket}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 166 |
file_path = os.path.join('users', 'data', filename)
|
| 167 |
try:
|
| 168 |
if AWS_ACCESS_KEY and AWS_SECRET_KEY:
|
|
|
|
| 177 |
s3_client = session.client('s3')
|
| 178 |
with open(file_path, 'wb') as f:
|
| 179 |
s3_client.download_fileobj(bucket, f"staging/users/{filename}", f)
|
| 180 |
+
logger.info(f"File {filename} downloaded successfully from S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 181 |
return True
|
| 182 |
except Exception as e:
|
| 183 |
+
logger.error(f"Error downloading file {filename} from S3: {e}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 184 |
if os.path.exists(file_path):
|
| 185 |
os.remove(file_path)
|
| 186 |
return False
|
| 187 |
|
| 188 |
def update_user(user):
|
| 189 |
+
user_id = user.user_id
|
| 190 |
+
function_name = update_user.__name__
|
| 191 |
+
logger.info(f"Updating user {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 192 |
user.save_user()
|
| 193 |
filename = f'{user.user_id}.pkl'
|
| 194 |
if upload_file_to_s3(filename):
|
| 195 |
+
logger.info(f"User {user.user_id} updated successfully in S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 196 |
os.remove(os.path.join('users', 'data', filename))
|
| 197 |
return True
|
| 198 |
else:
|
| 199 |
+
logger.error(f"Failed to update user {user.user_id} in S3", extra={'user_id': user_id, 'endpoint': function_name})
|
| 200 |
return False
|
| 201 |
|
| 202 |
def upload_mementos_to_db(user_id):
|
| 203 |
+
function_name = upload_mementos_to_db.__name__
|
| 204 |
+
logger.info(f"Uploading mementos to DB for user {user_id}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 205 |
# Database connection parameters
|
| 206 |
db_params = {
|
| 207 |
'dbname': 'ourcoach',
|
|
|
|
| 213 |
|
| 214 |
# Path to the folder containing JSON files for the user
|
| 215 |
folder_path = os.path.join("mementos", "to_upload", user_id)
|
| 216 |
+
total = len(os.listdir(folder_path))
|
| 217 |
try:
|
| 218 |
with psycopg2.connect(**db_params) as conn:
|
| 219 |
with conn.cursor() as cursor:
|
|
|
|
| 236 |
cursor.execute(insert_query, list(values))
|
| 237 |
conn.commit()
|
| 238 |
os.remove(file_path)
|
| 239 |
+
logger.info(f"Uploaded memento {filename} ({cursor.rowcount}/{total})", extra={'user_id': user_id, 'endpoint': function_name})
|
| 240 |
+
|
| 241 |
+
logger.info(f"Successfully uploaded mementos for user {user_id} to DB", extra={'user_id': user_id, 'endpoint': function_name})
|
| 242 |
+
return True
|
| 243 |
except psycopg2.Error as e:
|
| 244 |
+
logger.error(f"Database connection error while uploading mementos for user {user_id}: {e}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 245 |
+
raise ConnectionError("Could not connect to the database")
|
| 246 |
except Exception as e:
|
| 247 |
+
logger.error(f"Error uploading mementos for user {user_id}: {e}", extra={'user_id': user_id, 'endpoint': function_name})
|
| 248 |
+
return False
|