Spaces:
Sleeping
Sleeping
File size: 3,466 Bytes
400552c 78f9503 400552c d2d3ca7 400552c 9135c43 400552c 78f9503 9135c43 78f9503 d2d3ca7 78f9503 d2d3ca7 9135c43 d2d3ca7 78f9503 400552c 78f9503 e41e611 9135c43 78f9503 9135c43 78f9503 |
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 |
# Standard library imports
import os.path
# Third-party imports
import gradio as gr
from dotenv import load_dotenv
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain.prompts import ChatPromptTemplate
from langchain.schema import HumanMessage, AIMessage
from langchain_community.utilities import SQLDatabase
from langchain_community.agent_toolkits.sql.toolkit import SQLDatabaseToolkit
from langchain_openai import ChatOpenAI
# Local imports
from init_db import Project, db_description, json_structure
# Load environment variables
load_dotenv()
# Check if database exists
if not os.path.exists('estate.db'):
raise FileNotFoundError(
"Database file 'estate.db' not found. Please run 'uv run init_db.py' first."
)
# Initialize model and database
model = ChatOpenAI(model="o3-mini-2025-01-31", streaming=True)
db = SQLDatabase.from_uri("sqlite:///estate.db")
# Set up SQL toolkit and tools
toolkit = SQLDatabaseToolkit(db=db, llm=model)
tools = toolkit.get_tools()
sql_distance_query = """
SELECT
id,
url,
structure->>'$.lat' AS lat,
structure->>'$.lng' AS lng,
(6371000 * acos(
cos(radians(50.08804)) * cos(radians(CAST(structure->>'$.lat' AS FLOAT))) *
cos(radians(CAST(structure->>'$.lng' AS FLOAT)) - radians(14.42076)) +
sin(radians(50.08804)) * sin(radians(CAST(structure->>'$.lat' AS FLOAT)))
)) AS distance
FROM project
WHERE structure->>'$.lat' IS NOT NULL
AND structure->>'$.lng' IS NOT NULL
ORDER BY distance ASC
LIMIT 5;
"""
# Get the OpenAI tools agent prompt
prompt = ChatPromptTemplate.from_messages([
("system", f"You are a helpful assistant that presents information about real estate projects in database for investors. Before executing queries make surey youhave schema of dabatase and first rows. This JSON structure info can help you: {json_structure}."),
("placeholder", "{chat_history}"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
# Create the agent with OpenAI tools format
agent = create_openai_tools_agent(
llm=model,
tools=tools,
prompt=prompt
)
# Create agent executor
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True
)
def chat_with_sql(message, history):
try:
history_langchain_format = []
for msg in history:
if msg['role'] == "user":
history_langchain_format.append(HumanMessage(content=msg['content']))
elif msg['role'] == "assistant":
history_langchain_format.append(AIMessage(content=msg['content']))
history_langchain_format.append(HumanMessage(content=message))
response = agent_executor.invoke({"input": message, "history": history_langchain_format})
for i in range(len(response["output"])):
yield response["output"][:i+1]
except Exception as e:
yield f"Error: {str(e)}"
# Create the Gradio interface
count_projects = Project.select().where(Project.structure.is_null(False)).count()
demo = gr.ChatInterface(
fn=chat_with_sql,
title="Estate Chat",
description=f"Planning to buy a new apartment? Ask me about {count_projects} new buildings (novostavby) in Prague 🇨🇿",
examples=[
"Project with the lowest deposit before completion",
"Cheapest apartment in Prague",
"Best price per sqm in Prague"
],
type="messages"
)
if __name__ == "__main__":
demo.launch(share=False, debug=True) |