dipan004 commited on
Commit
b9befe1
·
verified ·
1 Parent(s): 35cd5eb

Update notes/llm_notes_generator.py

Browse files
Files changed (1) hide show
  1. notes/llm_notes_generator.py +58 -5
notes/llm_notes_generator.py CHANGED
@@ -66,7 +66,7 @@ class FlexibleFinancialNoteGenerator:
66
 
67
  "mistralai/mixtral-8x7b-instruct"
68
  ]
69
-
70
  def load_note_templates(self) -> Dict[str, Any]:
71
  try:
72
  if __name__ == "__main__":
@@ -276,13 +276,16 @@ GENERATE VALID JSON NOW (NO ADDITIONAL TEXT):"""
276
  self.api_url,
277
  headers=self.headers,
278
  json=payload,
279
- timeout=60
280
  )
281
  response.raise_for_status()
282
  result = response.json()
283
  content = result['choices'][0]['message']['content']
284
  logger.info(f"Successful response from {model}")
285
  return content
 
 
 
286
  except requests.exceptions.HTTPError as e:
287
  if e.response.status_code == 404:
288
  logger.warning(f"Model {model} not found (404), trying next model")
@@ -358,6 +361,47 @@ GENERATE VALID JSON NOW (NO ADDITIONAL TEXT):"""
358
 
359
  return None, None
360
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  def validate_and_fix_json(self, json_data: Dict[str, Any], note_number: str) -> Dict[str, Any]:
362
  fixed_data = json_data.copy()
363
 
@@ -377,7 +421,7 @@ GENERATE VALID JSON NOW (NO ADDITIONAL TEXT):"""
377
 
378
  metadata_note_num = fixed_data["metadata"].get("note_number")
379
  try:
380
- expected_note_num = int(note_number)
381
 
382
  if (metadata_note_num is None or
383
  metadata_note_num == 0 or
@@ -436,17 +480,26 @@ GENERATE VALID JSON NOW (NO ADDITIONAL TEXT):"""
436
  if "subcategories" not in struct_elem or not isinstance(struct_elem["subcategories"], list):
437
  struct_elem["subcategories"] = []
438
 
 
 
 
 
 
 
 
 
 
439
  if i > 0 and struct_elem.get("subcategories"):
440
  if "total" not in struct_elem:
441
  struct_elem["total"] = sum(
442
- sub.get("value", 0.0)
443
  for sub in struct_elem["subcategories"]
444
  if isinstance(sub, dict)
445
  )
446
 
447
  if "previous_total" not in struct_elem:
448
  struct_elem["previous_total"] = sum(
449
- sub.get("previous_value", 0.0)
450
  for sub in struct_elem["subcategories"]
451
  if isinstance(sub, dict)
452
  )
 
66
 
67
  "mistralai/mixtral-8x7b-instruct"
68
  ]
69
+
70
  def load_note_templates(self) -> Dict[str, Any]:
71
  try:
72
  if __name__ == "__main__":
 
276
  self.api_url,
277
  headers=self.headers,
278
  json=payload,
279
+ timeout=180
280
  )
281
  response.raise_for_status()
282
  result = response.json()
283
  content = result['choices'][0]['message']['content']
284
  logger.info(f"Successful response from {model}")
285
  return content
286
+ except requests.exceptions.Timeout:
287
+ logger.warning(f"Request to {model} timed out after 180s")
288
+ continue
289
  except requests.exceptions.HTTPError as e:
290
  if e.response.status_code == 404:
291
  logger.warning(f"Model {model} not found (404), trying next model")
 
361
 
362
  return None, None
363
 
364
+ def safe_numeric_value(self, value, default=0.0):
365
+ """Convert any value to a safe numeric float, defaulting to 0.0 if conversion fails."""
366
+ if value is None or value == '' or value == '-':
367
+ return default
368
+
369
+ try:
370
+ # If already a number, return it as float
371
+ if isinstance(value, (int, float)):
372
+ return float(value)
373
+
374
+ # Handle string numbers
375
+ if isinstance(value, str):
376
+ # Remove common non-numeric characters
377
+ cleaned = value.replace(',', '').replace('₹', '').replace('Rs', '').replace('Rs.', '').strip()
378
+
379
+ # Handle parentheses for negative numbers (accounting format)
380
+ if cleaned.startswith('(') and cleaned.endswith(')'):
381
+ cleaned = '-' + cleaned[1:-1]
382
+
383
+ # Handle negative numbers
384
+ is_negative = cleaned.startswith('-')
385
+ if is_negative:
386
+ cleaned = cleaned[1:]
387
+
388
+ # Remove any remaining non-numeric characters except decimal point
389
+ cleaned = ''.join(c for c in cleaned if c.isdigit() or c == '.')
390
+
391
+ if not cleaned or cleaned == '.':
392
+ return default
393
+
394
+ # Convert to number
395
+ result = float(cleaned)
396
+ return -result if is_negative else result
397
+
398
+ # Try direct conversion as last resort
399
+ return float(value)
400
+
401
+ except (ValueError, TypeError, AttributeError):
402
+ logger.warning(f"Could not convert value '{value}' to numeric, using default {default}")
403
+ return default
404
+
405
  def validate_and_fix_json(self, json_data: Dict[str, Any], note_number: str) -> Dict[str, Any]:
406
  fixed_data = json_data.copy()
407
 
 
421
 
422
  metadata_note_num = fixed_data["metadata"].get("note_number")
423
  try:
424
+ expected_note_num = int(note_number);
425
 
426
  if (metadata_note_num is None or
427
  metadata_note_num == 0 or
 
480
  if "subcategories" not in struct_elem or not isinstance(struct_elem["subcategories"], list):
481
  struct_elem["subcategories"] = []
482
 
483
+ # FIX: Ensure all subcategory values are numeric before summing
484
+ for sub in struct_elem.get("subcategories", []):
485
+ if isinstance(sub, dict):
486
+ if "value" in sub:
487
+ sub["value"] = self.safe_numeric_value(sub["value"])
488
+ if "previous_value" in sub:
489
+ sub["previous_value"] = self.safe_numeric_value(sub["previous_value"])
490
+
491
+ # Now safely calculate totals
492
  if i > 0 and struct_elem.get("subcategories"):
493
  if "total" not in struct_elem:
494
  struct_elem["total"] = sum(
495
+ self.safe_numeric_value(sub.get("value", 0.0))
496
  for sub in struct_elem["subcategories"]
497
  if isinstance(sub, dict)
498
  )
499
 
500
  if "previous_total" not in struct_elem:
501
  struct_elem["previous_total"] = sum(
502
+ self.safe_numeric_value(sub.get("previous_value", 0.0))
503
  for sub in struct_elem["subcategories"]
504
  if isinstance(sub, dict)
505
  )