File size: 5,346 Bytes
c077032
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23baa4a
c077032
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c9c4066
c077032
d8369ce
c9c4066
 
 
 
 
 
 
 
 
 
 
d8369ce
166db18
 
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import os
import gradio as gr
import pandas as pd
from sqlalchemy import create_engine, MetaData, Table, Column, String, Integer, Float, insert, text, inspect
from smolagents import tool, CodeAgent, InferenceClientModel

# --- Setup SQLite database ---
engine = create_engine("sqlite:///data.db")
metadata_obj = MetaData()

# --- Create students table ---
students = Table(
    "students",
    metadata_obj,
    Column("student_id", Integer, primary_key=True),
    Column("student_name", String(32), nullable=False),
)
metadata_obj.create_all(engine)

# Insert sample student data
student_rows = [
    {"student_id": 1, "student_name": "Alice Johnson"},
    {"student_id": 2, "student_name": "Bob Smith"},
    {"student_id": 3, "student_name": "Charlie Brown"},
    {"student_id": 4, "student_name": "Diana Prince"},
]
for row in student_rows:
    stmt = insert(students).values(**row)
    with engine.begin() as conn:
        conn.execute(stmt)

# --- Create subjects table ---
subjects = Table(
    "subjects",
    metadata_obj,
    Column("student_id", Integer, primary_key=True),
    Column("subject_name", String(32), primary_key=True),
    Column("marks", Float, nullable=False),
    Column("teacher", String(32), nullable=False),
)
metadata_obj.create_all(engine)

# Insert sample subject/marks data
subject_rows = [
    {"student_id": 1, "subject_name": "Math", "marks": 95.0, "teacher": "Mr. Adams"},
    {"student_id": 1, "subject_name": "English", "marks": 88.5, "teacher": "Ms. Baker"},
    {"student_id": 1, "subject_name": "Science", "marks": 92.0, "teacher": "Dr. Carter"},
    {"student_id": 2, "subject_name": "Math", "marks": 72.0, "teacher": "Mr. Adams"},
    {"student_id": 2, "subject_name": "Science", "marks": 81.0, "teacher": "Dr. Carter"},
    {"student_id": 3, "subject_name": "Math", "marks": 85.0, "teacher": "Mr. Adams"},
    {"student_id": 3, "subject_name": "History", "marks": 90.0, "teacher": "Mrs. Davis"},
    {"student_id": 4, "subject_name": "English", "marks": 78.0, "teacher": "Ms. Baker"},
    {"student_id": 4, "subject_name": "Science", "marks": 82.0, "teacher": "Dr. Carter"},
]
for row in subject_rows:
    stmt = insert(subjects).values(**row)
    with engine.begin() as conn:
        conn.execute(stmt)

# --- Convert tables to DataFrames for front-end display ---
def fetch_table(table_name: str) -> pd.DataFrame:
    with engine.connect() as con:
        rows = con.execute(text(f"SELECT * FROM {table_name}"))
        df = pd.DataFrame(rows.fetchall(), columns=rows.keys())
    return df

students_df = fetch_table("students")
subjects_df = fetch_table("subjects")

# --- Define SQL tool for the agent ---
@tool
def sql_engine(query: str) -> list:
    """
    Executes SQL queries on the available tables: students and subjects.

    Args:
        query (str): The SQL query string to execute.

    Returns:
        list: List of tuples containing the query results.
    """
    try:
        print(f"🧩 Executing query: {query}")
        with engine.connect() as con:
            rows = con.execute(text(query))
            results = [tuple(row) for row in rows]
        return results or []
    except Exception as e:
        return [f" SQL Error: {str(e)}"]

# Dynamically describe tables for the agent
updated_description = "You can run SQL queries on these tables:\n"
inspector = inspect(engine)
for table in ["students", "subjects"]:
    columns_info = [(col["name"], col["type"]) for col in inspector.get_columns(table)]
    table_description = f"\n\nTable '{table}':\nColumns:\n" + "\n".join(
        [f" - {name}: {col_type}" for name, col_type in columns_info]
    )
    updated_description += table_description

sql_engine.description = updated_description

# --- Create the agent ---
agent = CodeAgent(
    tools=[sql_engine],
    model=InferenceClientModel(
        "meta-llama/Meta-Llama-3-8B-Instruct",
        api_key=os.environ.get("HF_TOKEN")
    ),
)

# --- Sample prompts to display ---
sample_prompts = [
    "Which student scored highest in Math?",
    "List all subjects and marks for Alice Johnson.",
    "Who is the teacher of Science for Diana Prince?",
    "Show students who scored more than 80 in Science.",
    "Average marks per subject."
]

# --- Define Gradio interface ---
def ask_agent(question: str) -> str:
    """Ask the AI agent a question and return its answer."""
    try:
        result = agent.run(question)
        if isinstance(result, list):
            result_str = "\n".join(str(r) for r in result)
            return result_str or "No results."
        return str(result)
    except Exception as e:
        return f" Error: {str(e)}"

with gr.Blocks() as demo:
    gr.Markdown("##  Text to SQL Agent")
    gr.Markdown("### Students Table")
    gr.DataFrame(value=students_df, interactive=False)
    gr.Markdown("### Subjects Table")
    gr.DataFrame(value=subjects_df, interactive=False)
    gr.Markdown("### Ask questions about students, subjects, marks, and teachers")
    question_input = gr.Textbox(label="Your question", placeholder="e.g., Which student scored highest in Math?")
    answer_output = gr.Textbox(label="Agent response")
    gr.Markdown("### Sample Prompts")
    for prompt in sample_prompts:
        gr.Markdown(f"- {prompt}")
    question_input.submit(fn=ask_agent, inputs=question_input, outputs=answer_output)

demo.launch()