zenaight commited on
Commit ·
62054ce
1
Parent(s): f0b5ada
Enhance intent handling by adding transaction_type support
Browse files- Updated the chat_with_session_memory function to include transaction_type in the system message, improving clarity on user intentions.
- Modified the extract_and_update_intent function to incorporate transaction_type into the intent fields and added normalization guidelines for this field.
- Updated the database schema to include transaction_type in the user_intents table, ensuring proper data storage and retrieval.
- Added a migration script to safely add the transaction_type column if it doesn't already exist, maintaining database integrity.
- ai_chat.py +13 -3
- database.py +1 -0
- supabase_setup.sql +10 -0
ai_chat.py
CHANGED
|
@@ -70,6 +70,8 @@ def chat_with_session_memory(state):
|
|
| 70 |
f"\n\nUser's property search preferences (only mention if relevant to conversation):\n"
|
| 71 |
f"- Location: {intent_data.get('location_preference','[not set]')}\n"
|
| 72 |
)
|
|
|
|
|
|
|
| 73 |
if intent_data.get('budget'):
|
| 74 |
system_message += f"- Budget: {intent_data.get('budget')} per month\n"
|
| 75 |
if intent_data.get('size_preference_sqm'):
|
|
@@ -228,7 +230,7 @@ async def extract_and_update_persona(state):
|
|
| 228 |
|
| 229 |
async def extract_and_update_intent(state):
|
| 230 |
print("DEBUG - Starting extract_and_update_intent")
|
| 231 |
-
intent_fields = ["location_preference", "budget", "size_preference_sqm", "must_have"]
|
| 232 |
user_message = state["user_message"]
|
| 233 |
session_id = state["session_id"]
|
| 234 |
intent = state.get("intent", {})
|
|
@@ -242,6 +244,7 @@ async def extract_and_update_intent(state):
|
|
| 242 |
- Budget: {intent.get('budget', 'Not set')}
|
| 243 |
- Size: {intent.get('size_preference_sqm', 'Not set')} sqm
|
| 244 |
- Must-haves: {intent.get('must_have', [])}
|
|
|
|
| 245 |
|
| 246 |
Instructions:
|
| 247 |
1. Normalize abbreviations and common terms:
|
|
@@ -253,8 +256,11 @@ async def extract_and_update_intent(state):
|
|
| 253 |
- If adding: Include both existing and new items in the array
|
| 254 |
- If changing: Replace with new requirements
|
| 255 |
- If clarifying: Update with more specific versions
|
| 256 |
-
3.
|
| 257 |
-
|
|
|
|
|
|
|
|
|
|
| 258 |
"""
|
| 259 |
|
| 260 |
response = await llm.ainvoke([{"role":"user","content":extraction_prompt}])
|
|
@@ -425,6 +431,10 @@ Examples of search_listings (user explicitly asking for properties):
|
|
| 425 |
- "Show me properties"
|
| 426 |
- "What do you have available?"
|
| 427 |
- "I'm looking for properties in Cape Town"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 428 |
|
| 429 |
Examples of other (NOT property searches):
|
| 430 |
- "Hi" → other
|
|
|
|
| 70 |
f"\n\nUser's property search preferences (only mention if relevant to conversation):\n"
|
| 71 |
f"- Location: {intent_data.get('location_preference','[not set]')}\n"
|
| 72 |
)
|
| 73 |
+
if intent_data.get('transaction_type'):
|
| 74 |
+
system_message += f"- Looking to: {intent_data.get('transaction_type')}\n"
|
| 75 |
if intent_data.get('budget'):
|
| 76 |
system_message += f"- Budget: {intent_data.get('budget')} per month\n"
|
| 77 |
if intent_data.get('size_preference_sqm'):
|
|
|
|
| 230 |
|
| 231 |
async def extract_and_update_intent(state):
|
| 232 |
print("DEBUG - Starting extract_and_update_intent")
|
| 233 |
+
intent_fields = ["location_preference", "budget", "size_preference_sqm", "must_have", "transaction_type"]
|
| 234 |
user_message = state["user_message"]
|
| 235 |
session_id = state["session_id"]
|
| 236 |
intent = state.get("intent", {})
|
|
|
|
| 244 |
- Budget: {intent.get('budget', 'Not set')}
|
| 245 |
- Size: {intent.get('size_preference_sqm', 'Not set')} sqm
|
| 246 |
- Must-haves: {intent.get('must_have', [])}
|
| 247 |
+
- Transaction: {intent.get('transaction_type', 'Not set')}
|
| 248 |
|
| 249 |
Instructions:
|
| 250 |
1. Normalize abbreviations and common terms:
|
|
|
|
| 256 |
- If adding: Include both existing and new items in the array
|
| 257 |
- If changing: Replace with new requirements
|
| 258 |
- If clarifying: Update with more specific versions
|
| 259 |
+
3. For transaction_type field: Normalize to either 'lease' or 'buy':
|
| 260 |
+
- 'rent', 'rental', 'lease', 'leasing', 'to rent' → 'rent'
|
| 261 |
+
- 'buy', 'purchase', 'buying', 'sale', 'for sale', 'to buy' → 'buy'
|
| 262 |
+
4. If the user is asking a definition or clarification (e.g. 'What does square metre mean?'), answer that question fully and do not update the intent.
|
| 263 |
+
5. Return only a JSON object with keys {intent_fields}, using null for unknown.
|
| 264 |
"""
|
| 265 |
|
| 266 |
response = await llm.ainvoke([{"role":"user","content":extraction_prompt}])
|
|
|
|
| 431 |
- "Show me properties"
|
| 432 |
- "What do you have available?"
|
| 433 |
- "I'm looking for properties in Cape Town"
|
| 434 |
+
- "I want to rent a warehouse in Johannesburg"
|
| 435 |
+
- "Looking to buy office space in Sandton"
|
| 436 |
+
- "Do you have any rentals available?"
|
| 437 |
+
- "What's for sale in Cape Town?"
|
| 438 |
|
| 439 |
Examples of other (NOT property searches):
|
| 440 |
- "Hi" → other
|
database.py
CHANGED
|
@@ -262,6 +262,7 @@ async def get_or_create_user_intent(session_id: str, wa_id: str) -> dict:
|
|
| 262 |
"budget": None,
|
| 263 |
"size_preference_sqm": None,
|
| 264 |
"must_have": None,
|
|
|
|
| 265 |
"created_at": datetime.utcnow().isoformat(),
|
| 266 |
"updated_at": datetime.utcnow().isoformat()
|
| 267 |
}
|
|
|
|
| 262 |
"budget": None,
|
| 263 |
"size_preference_sqm": None,
|
| 264 |
"must_have": None,
|
| 265 |
+
"transaction_type": None,
|
| 266 |
"created_at": datetime.utcnow().isoformat(),
|
| 267 |
"updated_at": datetime.utcnow().isoformat()
|
| 268 |
}
|
supabase_setup.sql
CHANGED
|
@@ -43,10 +43,20 @@ CREATE TABLE IF NOT EXISTS user_intents (
|
|
| 43 |
budget INTEGER,
|
| 44 |
size_preference_sqm INTEGER,
|
| 45 |
must_have TEXT[],
|
|
|
|
| 46 |
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
| 47 |
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 48 |
);
|
| 49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
-- Create properties table for property listings
|
| 51 |
CREATE TABLE IF NOT EXISTS properties (
|
| 52 |
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
| 43 |
budget INTEGER,
|
| 44 |
size_preference_sqm INTEGER,
|
| 45 |
must_have TEXT[],
|
| 46 |
+
transaction_type TEXT CHECK (transaction_type IN ('rent', 'buy')),
|
| 47 |
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
| 48 |
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 49 |
);
|
| 50 |
|
| 51 |
+
-- Migration: Add transaction_type column to existing user_intents table (if it doesn't exist)
|
| 52 |
+
DO $$
|
| 53 |
+
BEGIN
|
| 54 |
+
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
| 55 |
+
WHERE table_name = 'user_intents' AND column_name = 'transaction_type') THEN
|
| 56 |
+
ALTER TABLE user_intents ADD COLUMN transaction_type TEXT CHECK (transaction_type IN ('rent', 'buy'));
|
| 57 |
+
END IF;
|
| 58 |
+
END $$;
|
| 59 |
+
|
| 60 |
-- Create properties table for property listings
|
| 61 |
CREATE TABLE IF NOT EXISTS properties (
|
| 62 |
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|