Spaces:
Paused
Paused
| import os | |
| import httpx | |
| from crewai import Agent | |
| from crewai.tools import BaseTool | |
| from langchain_community.agent_toolkits.sql.base import create_sql_agent | |
| from langchain.prompts import PromptTemplate | |
| from langchain_community.agent_toolkits import SQLDatabaseToolkit | |
| from langchain_community.utilities import SQLDatabase | |
| from langchain_openai import ChatOpenAI | |
| from src.constants import MODEL_NAME | |
| # ✅ **Set SQLite Database Path to Work on Hugging Face Spaces** | |
| BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) # Project root directory | |
| DB_PATH = os.path.join(BASE_DIR, "src", "appointments.db") # Database inside `src/` | |
| # ✅ **Print database path for debugging** | |
| print(f"📂 Using Database Path: {DB_PATH}") | |
| # ✅ **Ensure database file exists** | |
| if not os.path.exists(DB_PATH): | |
| print("⚠️ WARNING: appointments.db not found! Make sure it's uploaded.") | |
| class DoctorInfoAgent: | |
| """ | |
| An agent to analyze doctor availability data and handle SQL queries related to doctor scheduling. | |
| """ | |
| def __init__(self): | |
| """ | |
| Initializes the DoctorInfoAgent with a role and tool for analyzing doctor availability data. | |
| """ | |
| self.doctor_slots_agent = Agent( | |
| role="Doctor Availability Checker and Slot Booking", | |
| goal="Analyze doctor availability data and book slots if asked", | |
| backstory="Expert at analyzing complex datasets using SQL", | |
| tools=[SlotsQueryTool(result_as_answer=True)], | |
| verbose=True, | |
| ) | |
| class SlotsQueryTool(BaseTool): | |
| """ | |
| A tool for running SQL queries and analyzing database data related to doctor availability. | |
| """ | |
| name: str = "sql_query_tool" | |
| description: str = "Run SQL queries and analyze database data" | |
| def _run(self, query: str) -> str: | |
| """ | |
| Executes an SQL query to analyze doctor availability data. | |
| Args: | |
| query (str): The SQL query string to be executed. | |
| Returns: | |
| str: The output of the query execution as a string. | |
| """ | |
| llm = ChatOpenAI( | |
| temperature=0, | |
| model_name=MODEL_NAME, | |
| max_tokens=500, | |
| http_client=httpx.Client(verify=False), | |
| ) | |
| template = ''' | |
| Answer the following questions as best you can. You have access to the following tools: | |
| {tools} | |
| Use the following format: | |
| Question: the input question you must answer | |
| Thought: you should always think about what to do | |
| Action: the action to take, should be one of [{tool_names}] | |
| Action Input: the input to the action | |
| Observation: the result of the action | |
| ... (this Thought/Action/Action Input/Observation can repeat N times) | |
| Thought: I now know the final answer | |
| Final Answer: the final answer to the original input question | |
| Use LIKE operator with lowercase when matching a name. | |
| When a user is asking to book slots for any doctor, STRICTLY delete the corresponding row from the table. | |
| Begin! | |
| Question: {input} | |
| Thought:{agent_scratchpad}''' | |
| # ✅ **Updated: Use absolute database path** | |
| doctor_info_agent = create_sql_agent( | |
| llm=llm, | |
| toolkit=SQLDatabaseToolkit( | |
| db=SQLDatabase.from_uri(f"sqlite:///{DB_PATH}"), | |
| llm=llm | |
| ), | |
| prompt=PromptTemplate.from_template(template), | |
| verbose=True, | |
| handle_parsing_errors=True, | |
| ) | |
| return doctor_info_agent.invoke(query)["output"] | |
| def _arun(self, query: str) -> str: | |
| raise NotImplementedError("Async not supported") |