zenaight commited on
Commit
b77c962
·
1 Parent(s): 2f6ba3c

Refine property search logic and enhance fallback responses

Browse files

- Updated the `extract_and_search_properties` function to improve the property search process by implementing a multi-pass filtering strategy, allowing for more flexible search results based on user preferences.
- Enhanced fallback responses to provide clearer communication when no properties match the user's criteria, including suggestions for broader searches and notifications for future availability.
- Improved logging to track the filtering process and the state of the search, aiding in debugging and user experience.

Files changed (1) hide show
  1. ai_chat.py +68 -27
ai_chat.py CHANGED
@@ -2,7 +2,7 @@ from langgraph.graph import StateGraph, END
2
  from langchain_core.runnables import RunnableLambda
3
  from typing import TypedDict
4
  from config import llm, OPENAI_API_KEY
5
- from database import get_session_messages, save_message, update_user_persona, update_user_intent, search_properties
6
 
7
  def chat_with_session_memory(state):
8
  """Chat function with session-based memory"""
@@ -272,45 +272,86 @@ async def extract_and_search_properties(state):
272
  intent = state.get("intent", {})
273
  print(f"Intent data: {intent}")
274
 
275
- # Check if we have the minimum required fields for property search
276
  location = intent.get("location_preference")
277
- budget = intent.get("budget")
278
- size = intent.get("size_preference_sqm")
279
 
280
- print(f"Location: {location}, Budget: {budget}, Size: {size}")
281
 
282
- if not location or budget is None or size is None:
283
- # Missing required fields, skip property search
284
- print(f"Missing required fields - skipping property search")
285
  return {"response": None}
286
 
287
  # Prepare filters for property search
288
- filters = {
289
- "location_preference": location,
290
- "budget": budget,
291
- "size_preference_sqm": size,
292
- "must_have": intent.get("must_have", [])
293
- }
 
 
 
 
 
 
 
 
294
 
295
  print(f"Searching with filters: {filters}")
296
 
297
  # Search for properties
298
  properties = await search_properties(filters)
299
- print(f"Found {len(properties)} properties: {properties}")
300
  state["properties"] = properties
301
 
302
- if not properties:
303
- # No properties found, provide fallback suggestion
304
- print(f"No properties found - setting fallback message")
305
- state["response"] = (
306
- f"I don't have any active listings in {location} that match your criteria. "
307
- "Would you like me to broaden the search to nearby areas in our database?"
308
- )
309
- return state
310
-
311
- # Properties found, continue to chat
312
- print(f"Properties found - continuing to chat")
313
- return {"response": None}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
  # --- Build LangGraph ---
316
  graph = StateGraph(ChatState)
 
2
  from langchain_core.runnables import RunnableLambda
3
  from typing import TypedDict
4
  from config import llm, OPENAI_API_KEY
5
+ from database import get_session_messages, save_message, update_user_persona, update_user_intent, search_properties, end_session
6
 
7
  def chat_with_session_memory(state):
8
  """Chat function with session-based memory"""
 
272
  intent = state.get("intent", {})
273
  print(f"Intent data: {intent}")
274
 
275
+ # Check if we have the minimum required field for property search
276
  location = intent.get("location_preference")
 
 
277
 
278
+ print(f"Location: {location}")
279
 
280
+ if not location:
281
+ # Missing location, skip property search
282
+ print(f"Missing location - skipping property search")
283
  return {"response": None}
284
 
285
  # Prepare filters for property search
286
+ filters = {"location_preference": location}
287
+
288
+ # Add budget if set
289
+ if intent.get("budget") is not None:
290
+ filters["budget"] = intent["budget"]
291
+
292
+ # Add size if set
293
+ if intent.get("size_preference_sqm") is not None:
294
+ filters["size_preference_sqm"] = intent["size_preference_sqm"]
295
+
296
+ # Add must-have features if set
297
+ must_have = intent.get("must_have", [])
298
+ if must_have and len(must_have) > 0:
299
+ filters["must_have"] = must_have
300
 
301
  print(f"Searching with filters: {filters}")
302
 
303
  # Search for properties
304
  properties = await search_properties(filters)
 
305
  state["properties"] = properties
306
 
307
+ # Pass 1: strict filters
308
+ if properties:
309
+ return {"response": None}
310
+
311
+ # Pass 2: drop must-haves
312
+ if "must_have" in filters:
313
+ filters2 = {k: v for k, v in filters.items() if k != "must_have"}
314
+ props2 = await search_properties(filters2)
315
+ if props2:
316
+ state["properties"] = props2
317
+ state["response"] = (
318
+ "I don't have an exact match with those features, "
319
+ "but here are listings matching your location, budget and size."
320
+ )
321
+ return state
322
+
323
+ # Pass 3: drop size
324
+ if "size_preference_sqm" in filters2:
325
+ filters3 = {k: v for k, v in filters2.items() if k != "size_preference_sqm"}
326
+ props3 = await search_properties(filters3)
327
+ if props3:
328
+ state["properties"] = props3
329
+ state["response"] = (
330
+ "I don't have that exact size, "
331
+ "but here are listings matching your location and budget."
332
+ )
333
+ return state
334
+
335
+ # Pass 4: drop budget
336
+ if "budget" in filters3:
337
+ filters4 = {k: v for k, v in filters3.items() if k != "budget"}
338
+ props4 = await search_properties(filters4)
339
+ if props4:
340
+ state["properties"] = props4
341
+ state["response"] = (
342
+ f"I don't have listings within your budget in {filters4['location_preference']}, "
343
+ "but here are some options in that area."
344
+ )
345
+ return state
346
+
347
+ # Final fallback: no listings at all
348
+ state["response"] = (
349
+ f"I don't have any listings right now matching your criteria. "
350
+ "I'll notify you as soon as something becomes available. "
351
+ "Feel free to reach out any time!"
352
+ )
353
+ await end_session(state["session_id"])
354
+ return state
355
 
356
  # --- Build LangGraph ---
357
  graph = StateGraph(ChatState)