Lui3ui3ui commited on
Commit
61c6352
Β·
verified Β·
1 Parent(s): c623f8d

Upload 2 files

Browse files
Files changed (2) hide show
  1. agents.py +37 -1
  2. app.py +16 -1
agents.py CHANGED
@@ -94,6 +94,8 @@ def extract_json_array(text: str):
94
  json_str = re.sub(r'"\s*}\s*"', '"}', json_str)
95
  # Fix missing commas between objects
96
  json_str = re.sub(r'"\s*}\s*{', '"},{', json_str)
 
 
97
  return json.loads(json_str)
98
  except Exception as e3:
99
  print("[extract_json_array] JSON fixing failed:", e3)
@@ -138,6 +140,8 @@ def safe_json_parse(content: str, fallback_value=None):
138
  fixed_content = re.sub(r'"\s*}\s*"', '"}', fixed_content)
139
  # Fix missing commas between objects
140
  fixed_content = re.sub(r'"\s*}\s*{', '"},{', fixed_content)
 
 
141
  return json.loads(fixed_content)
142
  except Exception as e3:
143
  print(f"[safe_json_parse] JSON fixing failed: {e3}")
@@ -229,6 +233,36 @@ async def extract_books_node(state):
229
  books = manual_books
230
  print("[extract_books_node] Pattern-based extraction successful:", books)
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  print("[extract_books_node] Parsed books:", books)
233
 
234
  # Ensure books is a list and each book has required fields
@@ -475,6 +509,7 @@ async def reasoning_node(state):
475
  print("[reasoning_node] Validated final recommendations:", validated_recommendations)
476
  print("[reasoning_node] Final reasoning:\n", final_reasoning)
477
 
 
478
  result_state = {
479
  "final_recommendations": validated_recommendations,
480
  "final_reasoning": final_reasoning
@@ -483,7 +518,8 @@ async def reasoning_node(state):
483
  print("[reasoning_node] Returning state with keys:", list(result_state.keys()))
484
  print("[reasoning_node] πŸ‘ˆ exit with", result_state)
485
 
486
- return result_state
 
487
 
488
  except Exception as e:
489
  print("[reasoning_node] ❌ exception:", repr(e))
 
94
  json_str = re.sub(r'"\s*}\s*"', '"}', json_str)
95
  # Fix missing commas between objects
96
  json_str = re.sub(r'"\s*}\s*{', '"},{', json_str)
97
+ # Fix extra quotes around individual objects in arrays
98
+ json_str = re.sub(r'"\s*({[^}]+})\s*"', r'\1', json_str)
99
  return json.loads(json_str)
100
  except Exception as e3:
101
  print("[extract_json_array] JSON fixing failed:", e3)
 
140
  fixed_content = re.sub(r'"\s*}\s*"', '"}', fixed_content)
141
  # Fix missing commas between objects
142
  fixed_content = re.sub(r'"\s*}\s*{', '"},{', fixed_content)
143
+ # Fix extra quotes around individual objects in arrays
144
+ fixed_content = re.sub(r'"\s*({[^}]+})\s*"', r'\1', fixed_content)
145
  return json.loads(fixed_content)
146
  except Exception as e3:
147
  print(f"[safe_json_parse] JSON fixing failed: {e3}")
 
233
  books = manual_books
234
  print("[extract_books_node] Pattern-based extraction successful:", books)
235
 
236
+ # Additional fix: if books is a list but contains malformed strings, try to fix them
237
+ if isinstance(books, list) and books:
238
+ print("[extract_books_node] Checking for malformed book entries...")
239
+ fixed_books = []
240
+ for book in books:
241
+ if isinstance(book, str):
242
+ # Try to parse the string as JSON
243
+ try:
244
+ # Remove extra quotes around the object
245
+ cleaned_book = book.strip()
246
+ if cleaned_book.startswith('"') and cleaned_book.endswith('"'):
247
+ cleaned_book = cleaned_book[1:-1]
248
+ parsed_book = json.loads(cleaned_book)
249
+ if isinstance(parsed_book, dict) and parsed_book.get("title"):
250
+ fixed_books.append(parsed_book)
251
+ except:
252
+ # Try regex extraction as fallback
253
+ title_match = re.search(r'"title":\s*"([^"]+)"', book)
254
+ author_match = re.search(r'"author":\s*"([^"]+)"', book)
255
+ if title_match:
256
+ title = title_match.group(1)
257
+ author = author_match.group(1) if author_match else "Unknown"
258
+ fixed_books.append({"title": title, "author": author})
259
+ elif isinstance(book, dict) and book.get("title"):
260
+ fixed_books.append(book)
261
+
262
+ if fixed_books:
263
+ books = fixed_books
264
+ print("[extract_books_node] Fixed malformed book entries:", books)
265
+
266
  print("[extract_books_node] Parsed books:", books)
267
 
268
  # Ensure books is a list and each book has required fields
 
509
  print("[reasoning_node] Validated final recommendations:", validated_recommendations)
510
  print("[reasoning_node] Final reasoning:\n", final_reasoning)
511
 
512
+ # Return the new state with our data
513
  result_state = {
514
  "final_recommendations": validated_recommendations,
515
  "final_reasoning": final_reasoning
 
518
  print("[reasoning_node] Returning state with keys:", list(result_state.keys()))
519
  print("[reasoning_node] πŸ‘ˆ exit with", result_state)
520
 
521
+ # Try returning as a dict to ensure proper state handling
522
+ return dict(result_state)
523
 
524
  except Exception as e:
525
  print("[reasoning_node] ❌ exception:", repr(e))
app.py CHANGED
@@ -33,14 +33,29 @@ async def run_book_recommender(user_input):
33
  }
34
 
35
  # Ensure we have the expected keys in final_state
 
 
 
36
  if "final_recommendations" not in final_state:
 
37
  final_state["final_recommendations"] = []
38
  if "final_reasoning" not in final_state:
 
39
  final_state["final_reasoning"] = "⚠️ Missing reasoning data from graph execution."
40
 
41
- # Access the final state directly - the reasoning node returns these keys directly
42
  recs = final_state.get("final_recommendations", [])
43
  reasoning = final_state.get("final_reasoning", "")
 
 
 
 
 
 
 
 
 
 
44
 
45
  # Defensive formatting of recommendations
46
  try:
 
33
  }
34
 
35
  # Ensure we have the expected keys in final_state
36
+ print(f"πŸ” Final state keys: {list(final_state.keys())}")
37
+ print(f"πŸ” Final state content: {final_state}")
38
+
39
  if "final_recommendations" not in final_state:
40
+ print("⚠️ final_recommendations not found in final state")
41
  final_state["final_recommendations"] = []
42
  if "final_reasoning" not in final_state:
43
+ print("⚠️ final_reasoning not found in final state")
44
  final_state["final_reasoning"] = "⚠️ Missing reasoning data from graph execution."
45
 
46
+ # Access the final state - check both possible structures
47
  recs = final_state.get("final_recommendations", [])
48
  reasoning = final_state.get("final_reasoning", "")
49
+
50
+ # If not found in direct keys, check if they're nested under 'reasoning'
51
+ if not recs and "reasoning" in final_state:
52
+ reasoning_data = final_state.get("reasoning", {})
53
+ if isinstance(reasoning_data, dict):
54
+ recs = reasoning_data.get("final_recommendations", [])
55
+ reasoning = reasoning_data.get("final_reasoning", reasoning)
56
+
57
+ print(f"πŸ” Extracted recs: {recs}")
58
+ print(f"πŸ” Extracted reasoning (first 200 chars): {reasoning[:200] if reasoning else 'None'}...")
59
 
60
  # Defensive formatting of recommendations
61
  try: