zenaight commited on
Commit
0854d25
·
1 Parent(s): 4f58a18

Enhance property handling and update server configuration

Browse files

- Updated the `extract_and_search_properties` function to utilize existing properties in the state for specific classification requests, improving efficiency in handling user inquiries.
- Removed outdated property selection logic from the `handle_image_request` function to streamline the code and enhance clarity.
- Modified the server port in `main.py` from 7860 to 8000 to align with new configuration settings.
- Updated the README to reflect the new server port and ensure accurate setup instructions for users.
- These changes aim to improve the responsiveness and accuracy of property selections while providing clear guidance for application setup.

Files changed (5) hide show
  1. README.md +156 -156
  2. ai_chat.py +11 -34
  3. database.py +2 -2
  4. main.py +1 -1
  5. requirements.txt +10 -13
README.md CHANGED
@@ -1,156 +1,156 @@
1
- ---
2
- title: PropAgent
3
- emoji: 🤖
4
- colorFrom: blue
5
- colorTo: purple
6
- sdk: docker
7
- pinned: false
8
- short_description: WhatsApp AI Agent with Supabase integration
9
- ---
10
-
11
- # PropAgent - WhatsApp AI Agent
12
-
13
- A WhatsApp chatbot powered by OpenAI GPT-4 and integrated with Supabase for user management.
14
-
15
- ## Features
16
-
17
- - 🤖 AI-powered chat responses using OpenAI GPT-4
18
- - 📱 WhatsApp Business API integration
19
- - 👥 User management with Supabase database
20
- - 🔄 Conversation memory and context
21
- - 📊 User activity tracking
22
- - 🚀 RESTful API endpoints for user management
23
-
24
- ## Setup
25
-
26
- ### 1. Environment Variables
27
-
28
- Create a `.env` file with the following variables:
29
-
30
- ```bash
31
- # WhatsApp Business API
32
- VERIFY_TOKEN=your_webhook_verify_token
33
- PHONE_NUMBER_ID=your_phone_number_id
34
- WHATSAPP_API_TOKEN=your_whatsapp_api_token
35
-
36
- # OpenAI
37
- OPENAI_API_KEY=your_openai_api_key
38
-
39
- # Supabase
40
- SUPABASE_URL=your_supabase_project_url
41
- SUPABASE_KEY=your_supabase_anon_key
42
- ```
43
-
44
- ### 2. Supabase Setup
45
-
46
- 1. Create a new Supabase project at [supabase.com](https://supabase.com)
47
- 2. Go to the SQL Editor in your Supabase dashboard
48
- 3. Run the SQL script from `supabase_setup.sql` to create the users table
49
- 4. Copy your project URL and anon key from Settings > API
50
-
51
- ### 3. WhatsApp Business API Setup
52
-
53
- 1. Create a Meta Developer account
54
- 2. Set up a WhatsApp Business app
55
- 3. Configure webhook URL: `https://your-domain.com/webhook`
56
- 4. Set the verify token in your environment variables
57
-
58
- ### 4. Installation
59
-
60
- ```bash
61
- pip install -r requirements.txt
62
- ```
63
-
64
- ### 5. Running the Application
65
-
66
- ```bash
67
- uvicorn main:app --host 0.0.0.0 --port 7860
68
- ```
69
-
70
- ## API Endpoints
71
-
72
- ### Webhook Endpoints
73
- - `GET /webhook` - WhatsApp webhook verification
74
- - `POST /webhook` - Receive WhatsApp messages
75
-
76
- ### User Management
77
- - `GET /users/{wa_id}` - Get user by WhatsApp ID
78
- - `GET /users` - List all users (with pagination)
79
- - `PUT /users/{wa_id}` - Update user name
80
-
81
- ### Health & Testing
82
- - `GET /ping` - Simple health check
83
- - `GET /health` - Detailed service status
84
- - `POST /chat` - Direct AI chat endpoint
85
-
86
- ## Database Schema
87
-
88
- ### Users Table
89
- ```sql
90
- users
91
- -----
92
- - wa_id (TEXT, PRIMARY KEY) - WhatsApp user ID
93
- - name (TEXT) - User's display name
94
- - created_at (TIMESTAMP) - Account creation time
95
- - updated_at (TIMESTAMP) - Last activity time
96
- ```
97
-
98
- ## Features
99
-
100
- ### User Management
101
- - Automatic user creation when first message is received
102
- - User name updates from WhatsApp profile
103
- - Activity tracking with automatic timestamp updates
104
-
105
- ### AI Chat
106
- - Context-aware conversations using user names
107
- - Conversation memory (last 6 messages)
108
- - Error handling and fallback responses
109
-
110
- ### Security
111
- - Environment variable configuration
112
- - Optional Row Level Security (RLS) in Supabase
113
- - Input validation and error handling
114
-
115
- ## Project Structure
116
-
117
- ```
118
- PropAgent/
119
- ├── main.py # Main application entry point
120
- ├── config.py # Configuration and client setup
121
- ├── database.py # Supabase database operations
122
- ├── whatsapp.py # WhatsApp API integration
123
- ├── ai_chat.py # LangGraph AI conversation logic
124
- ├── api_routes.py # FastAPI route definitions
125
- ├── supabase_setup.sql # Database schema setup
126
- └── requirements.txt # Python dependencies
127
- ```
128
-
129
- ## Development
130
-
131
- The application uses a modular architecture:
132
- - **main.py** - Clean entry point focusing on core webhook logic
133
- - **config.py** - Environment variables and client initialization
134
- - **database.py** - All Supabase database operations
135
- - **whatsapp.py** - WhatsApp Business API integration
136
- - **ai_chat.py** - LangGraph conversation flow and AI processing
137
- - **api_routes.py** - REST API endpoints and webhook verification
138
-
139
- **Technologies:**
140
- - **FastAPI** for the web framework
141
- - **LangGraph** for conversation flow management
142
- - **OpenAI GPT-4** for AI responses
143
- - **Supabase** for user data storage
144
- - **WhatsApp Business API** for messaging
145
-
146
- ## Deployment
147
-
148
- The application includes a Dockerfile for containerized deployment. You can deploy it to:
149
- - Hugging Face Spaces
150
- - Railway
151
- - Heroku
152
- - Any container platform
153
-
154
- ## License
155
-
156
- MIT License
 
1
+ ---
2
+ title: PropAgent
3
+ emoji: 🤖
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ pinned: false
8
+ short_description: WhatsApp AI Agent with Supabase integration
9
+ ---
10
+
11
+ # PropAgent - WhatsApp AI Agent
12
+
13
+ A WhatsApp chatbot powered by OpenAI GPT-4 and integrated with Supabase for user management.
14
+
15
+ ## Features
16
+
17
+ - 🤖 AI-powered chat responses using OpenAI GPT-4
18
+ - 📱 WhatsApp Business API integration
19
+ - 👥 User management with Supabase database
20
+ - 🔄 Conversation memory and context
21
+ - 📊 User activity tracking
22
+ - 🚀 RESTful API endpoints for user management
23
+
24
+ ## Setup
25
+
26
+ ### 1. Environment Variables
27
+
28
+ Create a `.env` file with the following variables:
29
+
30
+ ```bash
31
+ # WhatsApp Business API
32
+ VERIFY_TOKEN=your_webhook_verify_token
33
+ PHONE_NUMBER_ID=your_phone_number_id
34
+ WHATSAPP_API_TOKEN=your_whatsapp_api_token
35
+
36
+ # OpenAI
37
+ OPENAI_API_KEY=your_openai_api_key
38
+
39
+ # Supabase
40
+ SUPABASE_URL=your_supabase_project_url
41
+ SUPABASE_KEY=your_supabase_anon_key
42
+ ```
43
+
44
+ ### 2. Supabase Setup
45
+
46
+ 1. Create a new Supabase project at [supabase.com](https://supabase.com)
47
+ 2. Go to the SQL Editor in your Supabase dashboard
48
+ 3. Run the SQL script from `supabase_setup.sql` to create the users table
49
+ 4. Copy your project URL and anon key from Settings > API
50
+
51
+ ### 3. WhatsApp Business API Setup
52
+
53
+ 1. Create a Meta Developer account
54
+ 2. Set up a WhatsApp Business app
55
+ 3. Configure webhook URL: `https://your-domain.com/webhook`
56
+ 4. Set the verify token in your environment variables
57
+
58
+ ### 4. Installation
59
+
60
+ ```bash
61
+ pip install -r requirements.txt
62
+ ```
63
+
64
+ ### 5. Running the Application
65
+
66
+ ```bash
67
+ uvicorn main:app --host 0.0.0.0 --port 8000
68
+ ```
69
+
70
+ ## API Endpoints
71
+
72
+ ### Webhook Endpoints
73
+ - `GET /webhook` - WhatsApp webhook verification
74
+ - `POST /webhook` - Receive WhatsApp messages
75
+
76
+ ### User Management
77
+ - `GET /users/{wa_id}` - Get user by WhatsApp ID
78
+ - `GET /users` - List all users (with pagination)
79
+ - `PUT /users/{wa_id}` - Update user name
80
+
81
+ ### Health & Testing
82
+ - `GET /ping` - Simple health check
83
+ - `GET /health` - Detailed service status
84
+ - `POST /chat` - Direct AI chat endpoint
85
+
86
+ ## Database Schema
87
+
88
+ ### Users Table
89
+ ```sql
90
+ users
91
+ -----
92
+ - wa_id (TEXT, PRIMARY KEY) - WhatsApp user ID
93
+ - name (TEXT) - User's display name
94
+ - created_at (TIMESTAMP) - Account creation time
95
+ - updated_at (TIMESTAMP) - Last activity time
96
+ ```
97
+
98
+ ## Features
99
+
100
+ ### User Management
101
+ - Automatic user creation when first message is received
102
+ - User name updates from WhatsApp profile
103
+ - Activity tracking with automatic timestamp updates
104
+
105
+ ### AI Chat
106
+ - Context-aware conversations using user names
107
+ - Conversation memory (last 6 messages)
108
+ - Error handling and fallback responses
109
+
110
+ ### Security
111
+ - Environment variable configuration
112
+ - Optional Row Level Security (RLS) in Supabase
113
+ - Input validation and error handling
114
+
115
+ ## Project Structure
116
+
117
+ ```
118
+ PropAgent/
119
+ ├── main.py # Main application entry point
120
+ ├── config.py # Configuration and client setup
121
+ ├── database.py # Supabase database operations
122
+ ├── whatsapp.py # WhatsApp API integration
123
+ ├── ai_chat.py # LangGraph AI conversation logic
124
+ ├── api_routes.py # FastAPI route definitions
125
+ ├── supabase_setup.sql # Database schema setup
126
+ └── requirements.txt # Python dependencies
127
+ ```
128
+
129
+ ## Development
130
+
131
+ The application uses a modular architecture:
132
+ - **main.py** - Clean entry point focusing on core webhook logic
133
+ - **config.py** - Environment variables and client initialization
134
+ - **database.py** - All Supabase database operations
135
+ - **whatsapp.py** - WhatsApp Business API integration
136
+ - **ai_chat.py** - LangGraph conversation flow and AI processing
137
+ - **api_routes.py** - REST API endpoints and webhook verification
138
+
139
+ **Technologies:**
140
+ - **FastAPI** for the web framework
141
+ - **LangGraph** for conversation flow management
142
+ - **OpenAI GPT-4** for AI responses
143
+ - **Supabase** for user data storage
144
+ - **WhatsApp Business API** for messaging
145
+
146
+ ## Deployment
147
+
148
+ The application includes a Dockerfile for containerized deployment. You can deploy it to:
149
+ - Hugging Face Spaces
150
+ - Railway
151
+ - Heroku
152
+ - Any container platform
153
+
154
+ ## License
155
+
156
+ MIT License
ai_chat.py CHANGED
@@ -371,6 +371,17 @@ async def extract_and_search_properties(state):
371
  classification = state.get("classification")
372
  print(f"DEBUG - Property search classification check: '{classification}'")
373
 
 
 
 
 
 
 
 
 
 
 
 
374
  # Check if classification matches our search categories
375
  is_search_request = (
376
  classification == "search_listings" or
@@ -575,40 +586,6 @@ async def handle_image_request(state):
575
  best_match_score = score
576
  selected_property = prop
577
 
578
- # Look for specific property selections in conversation
579
- session_messages = state.get("session_messages", [])
580
- recent_messages = session_messages[-20:] # Look at more messages
581
-
582
- # Look for patterns like "option 3", "the warehouse", "this property"
583
- selected_property_context = None
584
-
585
- for msg in recent_messages:
586
- if msg.get("role") == "user":
587
- content = msg.get("content", "").lower()
588
- # Look for option selections
589
- if "option" in content:
590
- import re
591
- option_match = re.search(r'option\s+(\d+)', content)
592
- if option_match:
593
- option_num = int(option_match.group(1))
594
- if 1 <= option_num <= len(props):
595
- selected_property_context = props[option_num - 1]
596
- print(f"DEBUG - Found user selected option {option_num}: {selected_property_context.get('title')}")
597
- break
598
-
599
- # Look for property type mentions that user specifically asked about
600
- for i, prop in enumerate(props):
601
- title_words = prop.get("title", "").lower().split()
602
- for word in ["warehouse", "office", "space", "unit"]:
603
- if word in content and word in title_words:
604
- selected_property_context = prop
605
- print(f"DEBUG - Found user interest in {word}: {prop.get('title')}")
606
- break
607
-
608
- # Use the property the user specifically selected/discussed
609
- if selected_property_context:
610
- selected_property = selected_property_context
611
-
612
  # Fallback: Use conversation context to find which property user was discussing
613
  if not selected_property and len(props) > 1:
614
  # Check conversation history for property context
 
371
  classification = state.get("classification")
372
  print(f"DEBUG - Property search classification check: '{classification}'")
373
 
374
+ # Check if this is a detail request for existing properties in state
375
+ existing_properties = state.get("properties", [])
376
+ if (classification.startswith("request_images") or
377
+ classification == "request_address" or
378
+ classification == "request_details") and existing_properties:
379
+ print(f"DEBUG - Using existing properties from state, count: {len(existing_properties)}")
380
+ return {
381
+ "properties": existing_properties,
382
+ "classification": classification
383
+ }
384
+
385
  # Check if classification matches our search categories
386
  is_search_request = (
387
  classification == "search_listings" or
 
586
  best_match_score = score
587
  selected_property = prop
588
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  # Fallback: Use conversation context to find which property user was discussing
590
  if not selected_property and len(props) > 1:
591
  # Check conversation history for property context
database.py CHANGED
@@ -329,8 +329,8 @@ async def search_properties(filters: dict) -> list:
329
  # Note: Must-have features are removed from database search
330
  # They will be handled by the LLM in the chat response
331
 
332
- # e. Order & limit
333
- query = query.order("is_featured", desc=True).order("price").limit(5)
334
 
335
  # f. Execute and return
336
  resp = query.execute()
 
329
  # Note: Must-have features are removed from database search
330
  # They will be handled by the LLM in the chat response
331
 
332
+ # e. Order & limit - prioritize recent activity, then featured, then price
333
+ query = query.order("updated_at", desc=True).order("is_featured", desc=True).order("price").limit(5)
334
 
335
  # f. Execute and return
336
  resp = query.execute()
main.py CHANGED
@@ -113,4 +113,4 @@ async def startup_event():
113
 
114
  if __name__ == "__main__":
115
  import uvicorn
116
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
113
 
114
  if __name__ == "__main__":
115
  import uvicorn
116
+ uvicorn.run(app, host="0.0.0.0", port=8000)
requirements.txt CHANGED
@@ -1,13 +1,10 @@
1
- fastapi
2
- uvicorn
3
- python-dotenv
4
- httpx
5
- openai
6
- langchain
7
- langchain-openai
8
- langgraph
9
- langchain-core
10
- supabase
11
- Pillow
12
- requests
13
- aiofiles
 
1
+ fastapi
2
+ uvicorn
3
+ python-dotenv
4
+ httpx
5
+ openai
6
+ langchain
7
+ langchain-openai
8
+ langgraph
9
+ langchain-core
10
+ supabase