rairo commited on
Commit
d160019
·
verified ·
1 Parent(s): bd957ec

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +178 -44
main.py CHANGED
@@ -1087,72 +1087,206 @@ def calculate_cost(duration_seconds):
1087
  @app.route('/api/projects/<project_id>/start-conversation', methods=['POST'])
1088
  def start_conversation(project_id):
1089
  """Start a conversational AI session for a project"""
1090
- t0 = time.time()
 
1091
 
1092
  try:
 
 
 
1093
  uid = verify_token(request.headers.get('Authorization'))
1094
  if not uid:
 
1095
  return jsonify({'error': 'Unauthorized'}), 401
 
 
1096
 
 
 
 
1097
  user_ref = db_ref.child(f'users/{uid}')
1098
  user = user_ref.get()
1099
  if not user:
 
1100
  return jsonify({'error': 'User not found'}), 404
 
 
1101
 
 
 
 
1102
  project = db_ref.child(f'projects/{project_id}').get()
1103
- if not project or project.get('uid') != uid:
 
1104
  return jsonify({'error': 'Project not found'}), 404
 
 
 
 
 
1105
 
1106
- data = request.get_json()
1107
- initial_message = data.get('message', 'Hello, I need help with my DIY project.')
1108
-
1109
- # Initialize conversational AI handler
1110
- ai_handler = ConversationalAIHandler()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1111
 
1112
- # Create or get existing agent
1113
- agent_id = ai_handler.create_or_get_agent(project_id, project)
 
 
 
 
 
 
 
 
 
1114
 
1115
- # Start conversation simulation
1116
- conversation_result = ai_handler.simulate_conversation(agent_id, initial_message)
 
 
 
 
 
 
 
 
 
 
 
 
1117
 
1118
- duration = time.time() - t0
1119
- cost = calculate_cost(duration)
1120
-
1121
- # Check credits
1122
- if user.get('credits', 0) < cost:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1123
  return jsonify({'error': 'Insufficient credits', 'needed': cost}), 402
 
 
1124
 
1125
- # Deduct credits
1126
- new_credits = user['credits'] - cost
1127
- user_ref.update({'credits': new_credits})
1128
-
1129
- # Log the conversation
1130
- conversation_id = f"{project_id}_{int(t0)}"
1131
- db_ref.child(f'conversations/{conversation_id}').set({
1132
- 'project_id': project_id,
1133
- 'uid': uid,
1134
- 'agent_id': agent_id,
1135
- 'initial_message': initial_message,
1136
- 'result': conversation_result,
1137
- 'duration_seconds': duration,
1138
- 'credits_used': cost,
1139
- 'created_at': int(t0)
1140
- })
1141
-
1142
- logger.info(f"User {uid} started conversation for project {project_id}, "
1143
- f"duration {duration:.1f}s, cost {cost} credits.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1144
 
1145
- return jsonify({
1146
- 'conversation_id': conversation_id,
1147
- 'agent_id': agent_id,
1148
- 'simulation_result': conversation_result,
1149
- 'durationSeconds': round(duration, 1),
1150
- 'creditsDeducted': cost,
1151
- 'remainingCredits': new_credits
1152
- }), 200
1153
 
1154
  except Exception as e:
1155
- logger.error(f"Error starting conversation: {str(e)}")
 
 
 
 
1156
  return jsonify({'error': 'Failed to start conversation'}), 500
1157
 
1158
  @app.route('/api/projects/<project_id>/continue-conversation', methods=['POST'])
 
1087
  @app.route('/api/projects/<project_id>/start-conversation', methods=['POST'])
1088
  def start_conversation(project_id):
1089
  """Start a conversational AI session for a project"""
1090
+ start_time = time.time()
1091
+ logger.info(f"[CONVERSATION] Starting conversation process for project: {project_id}")
1092
 
1093
  try:
1094
+ # Authorization timing
1095
+ auth_start = time.time()
1096
+ logger.info(f"[CONVERSATION] Starting authorization check for project: {project_id}")
1097
  uid = verify_token(request.headers.get('Authorization'))
1098
  if not uid:
1099
+ logger.error(f"[CONVERSATION] ERROR: Unauthorized access attempt for project: {project_id}")
1100
  return jsonify({'error': 'Unauthorized'}), 401
1101
+ auth_time = time.time() - auth_start
1102
+ logger.info(f"[CONVERSATION] Authorization completed in {auth_time:.3f}s for user: {uid}")
1103
 
1104
+ # User data fetch timing
1105
+ user_fetch_start = time.time()
1106
+ logger.info(f"[CONVERSATION] Fetching user data for uid: {uid}")
1107
  user_ref = db_ref.child(f'users/{uid}')
1108
  user = user_ref.get()
1109
  if not user:
1110
+ logger.error(f"[CONVERSATION] ERROR: User not found for uid: {uid}")
1111
  return jsonify({'error': 'User not found'}), 404
1112
+ user_fetch_time = time.time() - user_fetch_start
1113
+ logger.info(f"[CONVERSATION] User data fetch completed in {user_fetch_time:.3f}s, credits: {user.get('credits', 0)}")
1114
 
1115
+ # Project data fetch timing
1116
+ project_fetch_start = time.time()
1117
+ logger.info(f"[CONVERSATION] Fetching project data for project_id: {project_id}")
1118
  project = db_ref.child(f'projects/{project_id}').get()
1119
+ if not project:
1120
+ logger.error(f"[CONVERSATION] ERROR: Project not found for project_id: {project_id}")
1121
  return jsonify({'error': 'Project not found'}), 404
1122
+ if project.get('uid') != uid:
1123
+ logger.error(f"[CONVERSATION] ERROR: Project access denied - project_id: {project_id}, project_uid: {project.get('uid')}, requesting_uid: {uid}")
1124
+ return jsonify({'error': 'Project not found'}), 404
1125
+ project_fetch_time = time.time() - project_fetch_start
1126
+ logger.info(f"[CONVERSATION] Project data fetch completed in {project_fetch_time:.3f}s for project: {project.get('projectTitle', 'Unknown')}")
1127
 
1128
+ # Request data parsing timing
1129
+ data_parse_start = time.time()
1130
+ logger.info(f"[CONVERSATION] Parsing request data")
1131
+ try:
1132
+ data = request.get_json()
1133
+ if data is None:
1134
+ logger.error(f"[CONVERSATION] ERROR: No JSON data received in request")
1135
+ return jsonify({'error': 'No JSON data provided'}), 400
1136
+ initial_message = data.get('message', 'Hello, I need help with my DIY project.')
1137
+ logger.info(f"[CONVERSATION] Initial message: {initial_message[:100]}{'...' if len(initial_message) > 100 else ''}")
1138
+ except Exception as e:
1139
+ logger.error(f"[CONVERSATION] ERROR: Failed to parse request JSON: {str(e)}")
1140
+ return jsonify({'error': 'Invalid JSON data'}), 400
1141
+ data_parse_time = time.time() - data_parse_start
1142
+ logger.info(f"[CONVERSATION] Request data parsing completed in {data_parse_time:.3f}s")
1143
+
1144
+ # AI Handler initialization timing
1145
+ ai_init_start = time.time()
1146
+ logger.info(f"[CONVERSATION] Initializing ConversationalAIHandler")
1147
+ try:
1148
+ ai_handler = ConversationalAIHandler()
1149
+ logger.info(f"[CONVERSATION] ConversationalAIHandler initialized successfully")
1150
+ except Exception as e:
1151
+ logger.error(f"[CONVERSATION] ERROR: Failed to initialize ConversationalAIHandler: {str(e)}")
1152
+ return jsonify({'error': 'Failed to initialize AI handler'}), 500
1153
+ ai_init_time = time.time() - ai_init_start
1154
+ logger.info(f"[CONVERSATION] AI handler initialization completed in {ai_init_time:.3f}s")
1155
 
1156
+ # Agent creation/retrieval timing
1157
+ agent_start = time.time()
1158
+ logger.info(f"[CONVERSATION] Creating or getting agent for project: {project_id}")
1159
+ try:
1160
+ agent_id = ai_handler.create_or_get_agent(project_id, project)
1161
+ logger.info(f"[CONVERSATION] Agent created/retrieved successfully: {agent_id}")
1162
+ except Exception as e:
1163
+ logger.error(f"[CONVERSATION] ERROR: Failed to create/get agent: {str(e)}")
1164
+ return jsonify({'error': 'Failed to create AI agent'}), 500
1165
+ agent_time = time.time() - agent_start
1166
+ logger.info(f"[CONVERSATION] Agent creation/retrieval completed in {agent_time:.3f}s")
1167
 
1168
+ # Conversation simulation timing
1169
+ simulation_start = time.time()
1170
+ logger.info(f"[CONVERSATION] Starting conversation simulation with agent: {agent_id}")
1171
+ try:
1172
+ conversation_result = ai_handler.simulate_conversation(agent_id, initial_message)
1173
+ logger.info(f"[CONVERSATION] Conversation simulation completed successfully")
1174
+ logger.info(f"[CONVERSATION] Simulation result type: {type(conversation_result)}")
1175
+ if isinstance(conversation_result, dict):
1176
+ logger.info(f"[CONVERSATION] Simulation result keys: {list(conversation_result.keys())}")
1177
+ except Exception as e:
1178
+ logger.error(f"[CONVERSATION] ERROR: Failed to simulate conversation: {str(e)}")
1179
+ return jsonify({'error': 'Failed to simulate conversation'}), 500
1180
+ simulation_time = time.time() - simulation_start
1181
+ logger.info(f"[CONVERSATION] Conversation simulation completed in {simulation_time:.3f}s")
1182
 
1183
+ # Duration and cost calculation timing
1184
+ calc_start = time.time()
1185
+ duration = time.time() - start_time
1186
+ logger.info(f"[CONVERSATION] Total duration so far: {duration:.3f}s")
1187
+ try:
1188
+ cost = calculate_cost(duration)
1189
+ logger.info(f"[CONVERSATION] Calculated cost: {cost} credits")
1190
+ except Exception as e:
1191
+ logger.error(f"[CONVERSATION] ERROR: Failed to calculate cost: {str(e)}")
1192
+ return jsonify({'error': 'Failed to calculate cost'}), 500
1193
+ calc_time = time.time() - calc_start
1194
+ logger.info(f"[CONVERSATION] Cost calculation completed in {calc_time:.3f}s")
1195
+
1196
+ # Credit check timing
1197
+ credit_check_start = time.time()
1198
+ user_credits = user.get('credits', 0)
1199
+ logger.info(f"[CONVERSATION] Checking credits - User has: {user_credits}, Cost: {cost}")
1200
+ if user_credits < cost:
1201
+ logger.error(f"[CONVERSATION] ERROR: Insufficient credits - User: {user_credits}, Needed: {cost}")
1202
  return jsonify({'error': 'Insufficient credits', 'needed': cost}), 402
1203
+ credit_check_time = time.time() - credit_check_start
1204
+ logger.info(f"[CONVERSATION] Credit check completed in {credit_check_time:.3f}s")
1205
 
1206
+ # Credit deduction timing
1207
+ deduction_start = time.time()
1208
+ new_credits = user_credits - cost
1209
+ logger.info(f"[CONVERSATION] Deducting {cost} credits, new balance: {new_credits}")
1210
+ try:
1211
+ user_ref.update({'credits': new_credits})
1212
+ logger.info(f"[CONVERSATION] Credits updated successfully in database")
1213
+ except Exception as e:
1214
+ logger.error(f"[CONVERSATION] ERROR: Failed to update user credits: {str(e)}")
1215
+ return jsonify({'error': 'Failed to update credits'}), 500
1216
+ deduction_time = time.time() - deduction_start
1217
+ logger.info(f"[CONVERSATION] Credit deduction completed in {deduction_time:.3f}s")
1218
+
1219
+ # Conversation logging timing
1220
+ logging_start = time.time()
1221
+ conversation_id = f"{project_id}_{int(start_time)}"
1222
+ logger.info(f"[CONVERSATION] Logging conversation with ID: {conversation_id}")
1223
+ try:
1224
+ conversation_data = {
1225
+ 'project_id': project_id,
1226
+ 'uid': uid,
1227
+ 'agent_id': agent_id,
1228
+ 'initial_message': initial_message,
1229
+ 'result': conversation_result,
1230
+ 'duration_seconds': duration,
1231
+ 'credits_used': cost,
1232
+ 'created_at': int(start_time)
1233
+ }
1234
+ db_ref.child(f'conversations/{conversation_id}').set(conversation_data)
1235
+ logger.info(f"[CONVERSATION] Conversation logged successfully to database")
1236
+ except Exception as e:
1237
+ logger.error(f"[CONVERSATION] ERROR: Failed to log conversation: {str(e)}")
1238
+ return jsonify({'error': 'Failed to log conversation'}), 500
1239
+ logging_time = time.time() - logging_start
1240
+ logger.info(f"[CONVERSATION] Conversation logging completed in {logging_time:.3f}s")
1241
+
1242
+ # Response preparation timing
1243
+ response_start = time.time()
1244
+ total_duration = time.time() - start_time
1245
+ logger.info(f"[CONVERSATION] Preparing response, total duration: {total_duration:.3f}s")
1246
+ try:
1247
+ response_data = {
1248
+ 'conversation_id': conversation_id,
1249
+ 'agent_id': agent_id,
1250
+ 'simulation_result': conversation_result,
1251
+ 'durationSeconds': round(total_duration, 1),
1252
+ 'creditsDeducted': cost,
1253
+ 'remainingCredits': new_credits
1254
+ }
1255
+ logger.info(f"[CONVERSATION] Response prepared successfully")
1256
+ except Exception as e:
1257
+ logger.error(f"[CONVERSATION] ERROR: Failed to prepare response: {str(e)}")
1258
+ return jsonify({'error': 'Failed to prepare response'}), 500
1259
+ response_time = time.time() - response_start
1260
+ logger.info(f"[CONVERSATION] Response preparation completed in {response_time:.3f}s")
1261
+
1262
+ # Final success logging
1263
+ logger.info(f"[CONVERSATION] SUCCESS: User {uid} started conversation for project {project_id}, "
1264
+ f"duration {total_duration:.1f}s, cost {cost} credits.")
1265
+
1266
+ # Performance summary
1267
+ logger.info(f"[CONVERSATION] PERFORMANCE BREAKDOWN:")
1268
+ logger.info(f"[CONVERSATION] - Authorization: {auth_time:.3f}s")
1269
+ logger.info(f"[CONVERSATION] - User fetch: {user_fetch_time:.3f}s")
1270
+ logger.info(f"[CONVERSATION] - Project fetch: {project_fetch_time:.3f}s")
1271
+ logger.info(f"[CONVERSATION] - Data parsing: {data_parse_time:.3f}s")
1272
+ logger.info(f"[CONVERSATION] - AI init: {ai_init_time:.3f}s")
1273
+ logger.info(f"[CONVERSATION] - Agent creation: {agent_time:.3f}s")
1274
+ logger.info(f"[CONVERSATION] - Simulation: {simulation_time:.3f}s")
1275
+ logger.info(f"[CONVERSATION] - Cost calc: {calc_time:.3f}s")
1276
+ logger.info(f"[CONVERSATION] - Credit check: {credit_check_time:.3f}s")
1277
+ logger.info(f"[CONVERSATION] - Credit deduction: {deduction_time:.3f}s")
1278
+ logger.info(f"[CONVERSATION] - Conversation logging: {logging_time:.3f}s")
1279
+ logger.info(f"[CONVERSATION] - Response prep: {response_time:.3f}s")
1280
+ logger.info(f"[CONVERSATION] - TOTAL: {total_duration:.3f}s")
1281
 
1282
+ return jsonify(response_data), 200
 
 
 
 
 
 
 
1283
 
1284
  except Exception as e:
1285
+ total_duration = time.time() - start_time
1286
+ logger.error(f"[CONVERSATION] CRITICAL ERROR: Unhandled exception after {total_duration:.3f}s")
1287
+ logger.error(f"[CONVERSATION] Exception type: {type(e).__name__}")
1288
+ logger.error(f"[CONVERSATION] Exception message: {str(e)}")
1289
+ logger.error(f"[CONVERSATION] Exception traceback:", exc_info=True)
1290
  return jsonify({'error': 'Failed to start conversation'}), 500
1291
 
1292
  @app.route('/api/projects/<project_id>/continue-conversation', methods=['POST'])