feat: add clear cache
Browse files- app.py +3 -1
- langchain_mcp_client.py +9 -3
- postgre_mcp_server.py +10 -10
app.py
CHANGED
|
@@ -158,11 +158,13 @@ with gr.Blocks(css=custom_css, theme=xtheme) as demo:
|
|
| 158 |
with gr.Column(scale=1):
|
| 159 |
with gr.Accordion("Example Questions", open=True):
|
| 160 |
gr.Markdown("""
|
|
|
|
| 161 |
- π List all tables in database
|
| 162 |
- π₯ Total number of customers
|
| 163 |
- π Top 10 customers by ticket count
|
| 164 |
- π Ticket count by status and visualize
|
| 165 |
-
- π Average ticket reopen count per
|
|
|
|
| 166 |
""")
|
| 167 |
|
| 168 |
|
|
|
|
| 158 |
with gr.Column(scale=1):
|
| 159 |
with gr.Accordion("Example Questions", open=True):
|
| 160 |
gr.Markdown("""
|
| 161 |
+
- π Describe the database
|
| 162 |
- π List all tables in database
|
| 163 |
- π₯ Total number of customers
|
| 164 |
- π Top 10 customers by ticket count
|
| 165 |
- π Ticket count by status and visualize
|
| 166 |
+
- π Average ticket reopen count per month
|
| 167 |
+
- π§Ή Clear memory : `/clear-cache`
|
| 168 |
""")
|
| 169 |
|
| 170 |
|
langchain_mcp_client.py
CHANGED
|
@@ -36,13 +36,14 @@ async def lc_mcp_exec(request: str, history=None) -> Tuple[str, list]:
|
|
| 36 |
# Load table summary and server parameters
|
| 37 |
table_summary = load_table_summary(os.environ["TABLE_SUMMARY_PATH"])
|
| 38 |
server_params = get_server_params()
|
| 39 |
-
|
| 40 |
-
|
|
|
|
| 41 |
# Initialize the LLM for OpenAI
|
| 42 |
llm = init_chat_model(
|
| 43 |
model_provider=os.environ["OPENAI_MODEL_PROVIDER"],
|
| 44 |
model=os.environ["OPENAI_MODEL"],
|
| 45 |
-
api_key=
|
| 46 |
)
|
| 47 |
else:
|
| 48 |
# Initialize the LLM for Gemini
|
|
@@ -61,6 +62,11 @@ async def lc_mcp_exec(request: str, history=None) -> Tuple[str, list]:
|
|
| 61 |
tools = await load_and_enrich_tools(session)
|
| 62 |
agent = create_react_agent(llm, tools)
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
# Add new user message to memory
|
| 65 |
message_history.add_user_message(request)
|
| 66 |
|
|
|
|
| 36 |
# Load table summary and server parameters
|
| 37 |
table_summary = load_table_summary(os.environ["TABLE_SUMMARY_PATH"])
|
| 38 |
server_params = get_server_params()
|
| 39 |
+
|
| 40 |
+
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
|
| 41 |
+
if OPENAI_API_KEY:
|
| 42 |
# Initialize the LLM for OpenAI
|
| 43 |
llm = init_chat_model(
|
| 44 |
model_provider=os.environ["OPENAI_MODEL_PROVIDER"],
|
| 45 |
model=os.environ["OPENAI_MODEL"],
|
| 46 |
+
api_key=OPENAI_API_KEY
|
| 47 |
)
|
| 48 |
else:
|
| 49 |
# Initialize the LLM for Gemini
|
|
|
|
| 62 |
tools = await load_and_enrich_tools(session)
|
| 63 |
agent = create_react_agent(llm, tools)
|
| 64 |
|
| 65 |
+
# clear the memory
|
| 66 |
+
if request == "/clear-cache":
|
| 67 |
+
message_history.clear()
|
| 68 |
+
return "Memory cleared", []
|
| 69 |
+
|
| 70 |
# Add new user message to memory
|
| 71 |
message_history.add_user_message(request)
|
| 72 |
|
postgre_mcp_server.py
CHANGED
|
@@ -117,7 +117,7 @@ When a user submits a request, you must:
|
|
| 117 |
- Always show the SQL query you generate along with the execution result.
|
| 118 |
- Validate SQL syntax before execution.
|
| 119 |
- Never assume table or column names. Use tools to confirm structure.
|
| 120 |
-
- Use memory efficiently. Don
|
| 121 |
- If you generate a SQL query, immediately call the **execute_query** tool.
|
| 122 |
- If the user requests a visualization, call the **visualize_results** tool with:
|
| 123 |
- A visualization prompt starting with "plot" (e.g., "plot a bar chart showing sales by region").
|
|
@@ -487,12 +487,12 @@ async def generate_analytical_query(table_name: str) -> list[PromptMessage]:
|
|
| 487 |
|
| 488 |
@mcp.tool(
|
| 489 |
description="Identifies both explicit and implied foreign key relationships for a given table using schema analysis and naming patterns.")
|
| 490 |
-
def find_relationships(table_name: str,
|
| 491 |
"""Find both explicit and implied relationships for a table.
|
| 492 |
|
| 493 |
Args:
|
| 494 |
table_name: The name of the table to analyze relationships for
|
| 495 |
-
|
| 496 |
"""
|
| 497 |
try:
|
| 498 |
# First get explicit foreign key relationships
|
|
@@ -511,7 +511,7 @@ def find_relationships(table_name: str, schema: str = 'public') -> str:
|
|
| 511 |
ON ccu.constraint_name = tc.constraint_name
|
| 512 |
AND ccu.table_schema = tc.table_schema
|
| 513 |
WHERE tc.constraint_type = 'FOREIGN KEY'
|
| 514 |
-
AND tc.table_schema = {
|
| 515 |
AND tc.table_name = {table_name}
|
| 516 |
"""
|
| 517 |
|
|
@@ -521,7 +521,7 @@ def find_relationships(table_name: str, schema: str = 'public') -> str:
|
|
| 521 |
-- Get all ID-like columns from our table
|
| 522 |
SELECT column_name, data_type
|
| 523 |
FROM information_schema.columns
|
| 524 |
-
WHERE table_schema = {
|
| 525 |
AND table_name = {table_name}
|
| 526 |
AND (
|
| 527 |
column_name LIKE '%%id'
|
|
@@ -557,7 +557,7 @@ def find_relationships(table_name: str, schema: str = 'public') -> str:
|
|
| 557 |
ON c.table_schema = t.table_schema
|
| 558 |
AND c.table_name = t.table_name
|
| 559 |
AND (c.column_name = 'id' OR c.column_name = sc.column_name)
|
| 560 |
-
WHERE t.table_schema = {
|
| 561 |
AND t.table_name != {table_name} -- Exclude self-references
|
| 562 |
)
|
| 563 |
SELECT
|
|
@@ -619,10 +619,10 @@ async def visualize_results(json_data: dict, vis_prompt: str) -> str:
|
|
| 619 |
"""
|
| 620 |
try:
|
| 621 |
# Debug prints to see what's being received
|
| 622 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
|
| 627 |
# Convert JSON to DataFrame
|
| 628 |
df = pd.DataFrame(json_data["data"], columns=json_data["columns"])
|
|
|
|
| 117 |
- Always show the SQL query you generate along with the execution result.
|
| 118 |
- Validate SQL syntax before execution.
|
| 119 |
- Never assume table or column names. Use tools to confirm structure.
|
| 120 |
+
- Use memory efficiently. Don't rerun a tool unless necessary.
|
| 121 |
- If you generate a SQL query, immediately call the **execute_query** tool.
|
| 122 |
- If the user requests a visualization, call the **visualize_results** tool with:
|
| 123 |
- A visualization prompt starting with "plot" (e.g., "plot a bar chart showing sales by region").
|
|
|
|
| 487 |
|
| 488 |
@mcp.tool(
|
| 489 |
description="Identifies both explicit and implied foreign key relationships for a given table using schema analysis and naming patterns.")
|
| 490 |
+
def find_relationships(table_name: str, db_schema: str = 'public') -> str:
|
| 491 |
"""Find both explicit and implied relationships for a table.
|
| 492 |
|
| 493 |
Args:
|
| 494 |
table_name: The name of the table to analyze relationships for
|
| 495 |
+
db_schema: The schema name (defaults to 'public')
|
| 496 |
"""
|
| 497 |
try:
|
| 498 |
# First get explicit foreign key relationships
|
|
|
|
| 511 |
ON ccu.constraint_name = tc.constraint_name
|
| 512 |
AND ccu.table_schema = tc.table_schema
|
| 513 |
WHERE tc.constraint_type = 'FOREIGN KEY'
|
| 514 |
+
AND tc.table_schema = {db_schema}
|
| 515 |
AND tc.table_name = {table_name}
|
| 516 |
"""
|
| 517 |
|
|
|
|
| 521 |
-- Get all ID-like columns from our table
|
| 522 |
SELECT column_name, data_type
|
| 523 |
FROM information_schema.columns
|
| 524 |
+
WHERE table_schema = {db_schema}
|
| 525 |
AND table_name = {table_name}
|
| 526 |
AND (
|
| 527 |
column_name LIKE '%%id'
|
|
|
|
| 557 |
ON c.table_schema = t.table_schema
|
| 558 |
AND c.table_name = t.table_name
|
| 559 |
AND (c.column_name = 'id' OR c.column_name = sc.column_name)
|
| 560 |
+
WHERE t.table_schema = {db_schema}
|
| 561 |
AND t.table_name != {table_name} -- Exclude self-references
|
| 562 |
)
|
| 563 |
SELECT
|
|
|
|
| 619 |
"""
|
| 620 |
try:
|
| 621 |
# Debug prints to see what's being received
|
| 622 |
+
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
|
| 623 |
+
if OPENAI_API_KEY:
|
| 624 |
+
pllm = OpenAI(api_token=OPENAI_API_KEY)
|
| 625 |
+
pai.config.set({"llm": pllm})
|
| 626 |
|
| 627 |
# Convert JSON to DataFrame
|
| 628 |
df = pd.DataFrame(json_data["data"], columns=json_data["columns"])
|