File size: 4,834 Bytes
7a6c242 ea73781 7a6c242 8d944f0 7a6c242 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
from smolagents import tool, CodeAgent, InferenceClientModel
import os
import dotenv
from sqlalchemy import create_engine, text
import gradio as gr
dotenv.load_dotenv()
DB_PATH = "real_estate.db"
MODEL_ID = "Qwen/Qwen3-235B-A22B-Instruct-2507"
HF_TOKEN = os.environ.get("HF_TOKEN", None)
if HF_TOKEN is None:
raise RuntimeError("HF_TOKEN missing. Add it in Space Settings β Repository secrets.")
engine = create_engine(f"sqlite:///{DB_PATH}", echo=True, future=True)
@tool
def sql_engine(query: str) -> str:
"""
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:
Columns:
- id: TEXT β Unique identifier of the listing.
- ref: TEXT β Reference number of the property listing.
- bua: TEXT β Built-up area of the property in square feet.
- title: TEXT β Title or headline of the property listing.
- no_of_leads: BIGINT β Number of customer leads or inquiries for the property.
- location: TEXT β Full address or general location of the property.
- sublocation: TEXT β Sub-location or neighborhood within the main location.
- building: TEXT β Name of the building in which the property is located.
- unit: TEXT β Unit number or identifier within the building.
- price: FLOAT β Price of the property in AED (United Arab Emirates Dirham).
- 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).
- score: BIGINT β Quality or ranking score of the property (0β100 scale).
- beds: FLOAT β Number of bedrooms in the property.
- baths: FLOAT β Number of bathrooms in the property.
- property_for: TEXT β Type of contract: either "Rental" or "Sales".
- views: TEXT β List of view features (comma-separated, e.g., "Sea View, City View").
- features: TEXT β Comma-separated list of property features (e.g., "Balcony, Pool, Parking").
- furnishing: TEXT β Furnishing status (e.g., Partly Furnished, Unfurnished, Furnished, Fitted, Not Fitted, Shell And Core).
- assigned_agent_name: TEXT β Name of the agent currently assigned to the property.
- marketed_agent_name: TEXT β Name of the agent marketing the property.
- portals: TEXT β List of online portals where the property is listed (comma-separated).
Use LIKE for partial matches on fields like location, sublocation, building, features, and portals, assigned_agent_name, marketed_agent_name, views, features.
Args:
query (str): The SQL query to be executed.
"""
output = ""
with engine.connect() as connection:
result = connection.execute(text(query))
rows = result.fetchall()
if not rows:
return "No results found."
for row in rows:
output += str(row) + "\n"
return output.strip()
def make_agent():
agent = CodeAgent(model= InferenceClientModel(model_id=MODEL_ID, api_key=HF_TOKEN),
tools=[sql_engine],
description="A helpful agent that can answer questions about real estate properties in Dubai based on a database of listings.",
)
return agent
agent = make_agent()
def run_agent(user_request: str) -> str:
"""
Takes a natural language request, lets the agent decide the SQL via the tool,
and returns a friendly response.
"""
if not user_request or not user_request.strip():
return "Please enter a request."
try:
return agent.run(user_request.strip())
except Exception as e:
return f"Agent error: {e}"
# ---- Gradio UI ----
with gr.Blocks(title="Real Estate Text-to-SQL") as demo:
gr.Markdown(
"""
# π‘ Nazem's personal Driven Text-to-SQL Agent
Ask natural-language questions to the CRM's listings database.
**Examples**
- "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."
- "Show 5 apartments in Dubai Marina with β₯3 beds, β₯2 baths, price 1Mβ2M AED. Include id, title, location, price, beds, baths, features."
- "Top 10 cheapest villas in Palm Jumeirah with at least 4 bedrooms."
- "
"""
)
with gr.Row():
inp = gr.Textbox(label="Your request", lines=5, placeholder="Ask for properties, filters, columns, limitsβ¦")
btn = gr.Button("Run")
out = gr.Markdown(label="Response")
btn.click(run_agent, inputs=inp, outputs=out)
if __name__ == "__main__":
demo.launch() |