dhruv575 commited on
Commit
87aa5b7
·
1 Parent(s): 02a4d4e

Why is everything being falsified!!!

Browse files
Files changed (1) hide show
  1. controllers/log_controller.py +71 -45
controllers/log_controller.py CHANGED
@@ -176,77 +176,103 @@ def process_log_sync(log_id):
176
 
177
  def classify_activity(activity, workflow_info):
178
  """
179
- Classify an activity against available workflows
180
- Returns workflow_id if matched, None otherwise
 
181
  """
182
  try:
183
- # Check if OpenAI API key is set
184
  api_key = os.environ.get('OPENAI_API_KEY')
185
  if not api_key:
186
- logger.error("OPENAI_API_KEY environment variable is not set")
187
  return None
188
 
189
- # Create OpenAI client with correct parameters for the current version
190
  client = openai.OpenAI(api_key=api_key)
191
 
192
- # Prepare prompt for OpenAI
193
  workflows_text = "\n".join([
194
- f"Workflow {i+1}: {w['title']} - {w['description']}"
195
- for i, w in enumerate(workflow_info)
196
  ])
197
 
198
  prompt = f"""
199
- I need to classify a law enforcement activity into one of our defined workflows,
200
- or determine if it's a routine/mundane activity that doesn't match any workflow.
201
-
202
- Here are the available workflows:
203
  {workflows_text}
204
-
205
- Here is the activity:
206
- Activity: {activity['activity']}
207
- Full Text: {activity['text']}
208
  Time: {activity.get('time', 'Not specified')}
209
  Location: {activity.get('location', 'Not specified')}
210
-
211
- Please classify this activity into one of the workflows, or indicate it's mundane.
212
- Respond with just the workflow ID if it matches, or "mundane" if it doesn't match any workflow.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  """
214
 
215
- # Call OpenAI API
 
 
216
  response = client.chat.completions.create(
217
  model="gpt-4o-mini",
218
  messages=[
219
- {"role": "system", "content": "You are a law enforcement activity classifier that matches activities to defined workflows."},
220
  {"role": "user", "content": prompt}
221
- ]
 
222
  )
223
 
224
- # Get classification result
225
- result = response.choices[0].message.content.strip()
226
-
227
- # Check if result is a workflow ID or "mundane"
228
- if result == "mundane":
229
- return None
230
-
231
- # Find the workflow by ID or index
232
- for workflow in workflow_info:
233
- if workflow['id'] in result:
234
- return workflow['id']
235
- if workflow['title'] in result:
236
- return workflow['id']
237
-
238
- # If we got a number, try to use it as an index
239
  try:
240
- index = int(result) - 1
241
- if 0 <= index < len(workflow_info):
242
- return workflow_info[index]['id']
243
- except ValueError:
244
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
- return None
247
-
248
  except Exception as e:
249
- logger.error(f"Error classifying activity: {str(e)}")
 
 
250
  return None
251
 
252
  def get_log(current_user, log_id):
 
176
 
177
  def classify_activity(activity, workflow_info):
178
  """
179
+ Classify an activity against available workflows using an LLM.
180
+ Returns workflow_id if matched, None otherwise.
181
+ Includes enhanced logging and asks for justification from the LLM.
182
  """
183
  try:
 
184
  api_key = os.environ.get('OPENAI_API_KEY')
185
  if not api_key:
186
+ logger.error("OPENAI_API_KEY not found for classify_activity.")
187
  return None
188
 
 
189
  client = openai.OpenAI(api_key=api_key)
190
 
 
191
  workflows_text = "\n".join([
192
+ f"Workflow ID: {w['id']} | Title: {w['title']} | Description: {w['description']}"
193
+ for w in workflow_info
194
  ])
195
 
196
  prompt = f"""
197
+ Analyze the following law enforcement activity and decide if it matches one of the provided workflows or if it is a mundane activity.
198
+
199
+ Available Workflows:
 
200
  {workflows_text}
201
+
202
+ Activity Details:
203
+ Activity Description: {activity.get('activity', 'N/A')}
204
+ Full Text: {activity.get('text', 'N/A')}
205
  Time: {activity.get('time', 'Not specified')}
206
  Location: {activity.get('location', 'Not specified')}
207
+
208
+ Your Task:
209
+ 1. Determine if the activity clearly matches one of the workflow descriptions.
210
+ 2. If it matches, provide the corresponding Workflow ID.
211
+ 3. If it does not match any workflow, classify it as "mundane".
212
+ 4. Provide a brief justification for your decision (1-2 sentences).
213
+
214
+ Output Format:
215
+ Return a JSON object with two keys: "decision" and "justification".
216
+ - "decision": Should be the matching Workflow ID (string) or the string "mundane".
217
+ - "justification": Should be a brief string explaining your reasoning.
218
+
219
+ Example Match Response:
220
+ {{"decision": "60d21b4967d0d8992e610c87", "justification": "The activity describes a traffic stop, which matches the Traffic Violation workflow."}}
221
+
222
+ Example Mundane Response:
223
+ {{"decision": "mundane", "justification": "The activity describes routine patrol or administrative tasks not covered by any workflow."}}
224
  """
225
 
226
+ # Log the prompt being sent (use debug level for potentially sensitive info)
227
+ logger.debug(f"Sending classification prompt to OpenAI: \n{prompt}")
228
+
229
  response = client.chat.completions.create(
230
  model="gpt-4o-mini",
231
  messages=[
232
+ {"role": "system", "content": "You are an AI assistant helping classify law enforcement activities into predefined workflows. Respond ONLY in the requested JSON format."},
233
  {"role": "user", "content": prompt}
234
+ ],
235
+ response_format={"type": "json_object"} # Ensure JSON output
236
  )
237
 
238
+ # Parse the JSON response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  try:
240
+ content = response.choices[0].message.content
241
+ logger.debug(f"Received OpenAI classification response content: {content}")
242
+ result_json = json.loads(content)
243
+ decision = result_json.get("decision")
244
+ justification = result_json.get("justification", "No justification provided.")
245
+
246
+ logger.info(f"LLM Classification - Decision: {decision}, Justification: {justification}")
247
+
248
+ if decision == "mundane":
249
+ return None
250
+
251
+ # Check if the decision is a valid ObjectId and matches a known workflow ID
252
+ valid_workflow_ids = {w['id'] for w in workflow_info}
253
+ if decision in valid_workflow_ids:
254
+ try:
255
+ # Validate it's a proper ObjectId format, though it's already a string match
256
+ ObjectId(decision)
257
+ return decision # Return the matched workflow ID string
258
+ except Exception:
259
+ logger.warning(f"LLM returned a decision '{decision}' matching a workflow ID, but it's not a valid ObjectId format. Treating as unclassified.")
260
+ return None
261
+ else:
262
+ logger.warning(f"LLM returned a decision '{decision}' which is not 'mundane' and does not match any known workflow ID. Treating as unclassified.")
263
+ return None
264
+
265
+ except json.JSONDecodeError:
266
+ logger.error(f"Failed to decode JSON response from OpenAI: {content}")
267
+ return None
268
+ except Exception as parse_err:
269
+ logger.error(f"Error parsing OpenAI classification response: {parse_err}")
270
+ return None
271
 
 
 
272
  except Exception as e:
273
+ logger.error(f"Error in classify_activity function: {str(e)}")
274
+ import traceback
275
+ logger.error(traceback.format_exc())
276
  return None
277
 
278
  def get_log(current_user, log_id):