Koaris commited on
Commit
7a6c242
Β·
verified Β·
1 Parent(s): 57853f6

Upload 3 files

Browse files
Files changed (4) hide show
  1. .gitattributes +1 -0
  2. app.py +104 -0
  3. real_estate.db +3 -0
  4. requirements.txt +4 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ real_estate.db filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smolagents import tool, CodeAgent, InferenceClientModel
2
+ import os
3
+ import dotenv
4
+ from sqlalchemy import create_engine, text
5
+ import gradio as gr
6
+
7
+ dotenv.load_dotenv()
8
+
9
+ DB_PATH = "real_estate.db"
10
+ MODEL_ID = "openai/gpt-oss-120b"
11
+ HF_TOKEN = os.environ.get("HF_TOKEN", None)
12
+ if HF_TOKEN is None:
13
+ raise RuntimeError("HF_TOKEN missing. Add it in Space Settings β†’ Repository secrets.")
14
+
15
+ engine = create_engine(f"sqlite:///{DB_PATH}", echo=True, future=True)
16
+
17
+ @tool
18
+ def sql_engine(query: str) -> str:
19
+ """
20
+ Executes a SQL query on the 'real_estate.db' SQLite database and returns the results as a string. The database contains a table named 'real_estate' with the following schema:
21
+ Columns:
22
+ - id: TEXT β€” Unique identifier of the listing.
23
+ - ref: TEXT β€” Reference number of the property listing.
24
+ - title: TEXT β€” Title or headline of the property listing.
25
+ - no_of_leads: BIGINT β€” Number of customer leads or inquiries for the property.
26
+ - location: TEXT β€” Full address or general location of the property.
27
+ - sublocation: TEXT β€” Sub-location or neighborhood within the main location.
28
+ - building: TEXT β€” Name of the building in which the property is located.
29
+ - unit: TEXT β€” Unit number or identifier within the building.
30
+ - price: FLOAT β€” Price of the property in AED (United Arab Emirates Dirham).
31
+ - category: TEXT β€” Category or type of property (e.g., Apartment, Villa, Townhouse, Duplex, Penthouse, Hotel Apartment, Land Residential, Loft Apartment, Residential Building, Bungalow, Full Floor Residential, Bulk Units).
32
+ - score: BIGINT β€” Quality or ranking score of the property (0–100 scale).
33
+ - beds: FLOAT β€” Number of bedrooms in the property.
34
+ - baths: FLOAT β€” Number of bathrooms in the property.
35
+ - property_for: TEXT β€” Type of contract: either "Rental" or "Sales".
36
+ - views: TEXT β€” List of view features (comma-separated, e.g., "Sea View, City View").
37
+ - features: TEXT β€” Comma-separated list of property features (e.g., "Balcony, Pool, Parking").
38
+ - furnishing: TEXT β€” Furnishing status (e.g., Partly Furnished, Unfurnished, Furnished, Fitted, Not Fitted, Shell And Core).
39
+ - assigned_agent_name: TEXT β€” Name of the agent currently assigned to the property.
40
+ - marketed_agent_name: TEXT β€” Name of the agent marketing the property.
41
+ - portals: TEXT β€” List of online portals where the property is listed (comma-separated).
42
+
43
+ Use LIKE for partial matches on fields like location, sublocation, building, features, and portals, assigned_agent_name, marketed_agent_name, views, features.
44
+ Args:
45
+ query (str): The SQL query to be executed.
46
+
47
+ """
48
+ output = ""
49
+
50
+ with engine.connect() as connection:
51
+ result = connection.execute(text(query))
52
+ rows = result.fetchall()
53
+ if not rows:
54
+ return "No results found."
55
+ for row in rows:
56
+ output += str(row) + "\n"
57
+ return output.strip()
58
+
59
+ def make_agent():
60
+
61
+ agent = CodeAgent(model= InferenceClientModel(model_id=MODEL_ID, api_key=HF_TOKEN),
62
+ tools=[sql_engine],
63
+ description="A helpful agent that can answer questions about real estate properties in Dubai based on a database of listings.",
64
+ )
65
+
66
+ return agent
67
+
68
+ agent = make_agent()
69
+
70
+ def run_agent(user_request: str) -> str:
71
+ """
72
+ Takes a natural language request, lets the agent decide the SQL via the tool,
73
+ and returns a friendly response.
74
+ """
75
+ if not user_request or not user_request.strip():
76
+ return "Please enter a request."
77
+ try:
78
+ return agent.run(user_request.strip())
79
+ except Exception as e:
80
+ return f"Agent error: {e}"
81
+
82
+ # ---- Gradio UI ----
83
+ with gr.Blocks(title="Real Estate Text-to-SQL") as demo:
84
+ gr.Markdown(
85
+ """
86
+ # 🏑 Nazem's personal Driven Text-to-SQL Agent
87
+ Ask natural-language questions to the CRM's listings database.
88
+
89
+ **Examples**
90
+ - "Write me a message to send my client who is asking me to propose 3 properties to show him. He is looking for flat with 2 to 3 bedrooms a marina view and a swimming pool between 1 and 5 million AED."
91
+ - "Show 5 apartments in Dubai Marina with β‰₯3 beds, β‰₯2 baths, price 1M–2M AED. Include id, title, location, price, beds, baths, features."
92
+ - "Top 10 cheapest villas in Palm Jumeirah with at least 4 bedrooms."
93
+ - "
94
+ """
95
+ )
96
+ with gr.Row():
97
+ inp = gr.Textbox(label="Your request", lines=5, placeholder="Ask for properties, filters, columns, limits…")
98
+ btn = gr.Button("Run")
99
+ out = gr.Markdown(label="Response")
100
+
101
+ btn.click(run_agent, inputs=inp, outputs=out)
102
+
103
+ if __name__ == "__main__":
104
+ demo.launch()
real_estate.db ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b4c398984a2692840c6e999c0ab37fab993b6f598c7bdd7bafa3b1dc32aaa4a5
3
+ size 3088384
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ smolagents>=0.3
2
+ sqlalchemy>=2.0
3
+ gradio>=4.0
4
+ python-dotenv>=1.0