diff --git a/kits/sql-query-generator/README.md b/kits/sql-query-generator/README.md new file mode 100644 index 00000000..7fa47e6f --- /dev/null +++ b/kits/sql-query-generator/README.md @@ -0,0 +1,101 @@ +# SQL Query Generator + +An AI-powered agent that converts natural language questions into optimized SQL queries. Paste your database schema, ask a question in plain English, and get production-ready SQL with explanations, confidence scores, and assumption tracking. + +## What It Does + +- Takes a database schema (CREATE TABLE statements) and a plain English question +- Generates an optimized, read-only SQL SELECT query +- Returns a structured response with the query, explanation, tables used, assumptions, and confidence level +- Only generates SELECT statements — never INSERT, UPDATE, DELETE, DROP, or ALTER +- Produces standard SQL compatible with PostgreSQL, MySQL, and SQLite + +## Problem It Solves + +Writing SQL queries from scratch takes time, especially for complex joins, aggregations, and subqueries. This tool lets developers, analysts, and data teams quickly get a working query by describing what they need in plain English. It's also useful for learning SQL — the explanation and assumptions help users understand the query logic. + +## Prerequisites + +- [Node.js](https://nodejs.org) 18+ +- [Lamatic.ai](https://lamatic.ai) account with a deployed SQL query generation flow +- A configured LLM provider (e.g., Anthropic, OpenAI, Google) in Lamatic Studio + +## Setup + +### 1. Clone and navigate + +```bash +git clone https://github.com/Lamatic/AgentKit.git +cd AgentKit/kits/sql-query-generator/apps +``` + +### 2. Install dependencies + +```bash +npm install +``` + +### 3. Configure environment + +```bash +cp .env.example .env +``` + +Fill in your values: + +``` +SQL_QUERY_GENERATOR_FLOW_ID = "your-flow-id" +LAMATIC_API_URL = "https://your-org.lamatic.dev" +LAMATIC_PROJECT_ID = "your-project-id" +LAMATIC_API_KEY = "sk-your-api-key" +``` + +### 4. Run locally + +```bash +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) in your browser. + +## Usage + +1. Paste your database schema (CREATE TABLE statements) in the schema field +2. Type your question in plain English +3. Click "Generate SQL" +4. View the generated query, copy it, and read the explanation + +You can also click "Load sample" to try it with example data. + +## Deploy to Vercel + +1. Push to your fork +2. Import the repo on [Vercel](https://vercel.com) +3. Set root directory to `kits/sql-query-generator/apps` +4. Add environment variables +5. Deploy + +## Flow Architecture + +``` +API Request → Generate Text (LLM) → API Response +``` + +The flow uses a single LLM node with a carefully crafted system prompt that: +- Enforces read-only query generation +- Requires structured JSON output +- Handles ambiguous questions gracefully +- Tracks assumptions and confidence + +## Environment Variables + +| Variable | Description | +|---|---| +| `SQL_QUERY_GENERATOR_FLOW_ID` | The deployed Lamatic flow ID | +| `LAMATIC_API_URL` | Your Lamatic API endpoint URL | +| `LAMATIC_PROJECT_ID` | Your Lamatic project ID | +| `LAMATIC_API_KEY` | Your Lamatic secret API key | + +## Author + +**Aakriti** — [pandey.aakriti1@gmail.com](mailto:pandey.aakriti1@gmail.com) diff --git a/kits/sql-query-generator/agent.md b/kits/sql-query-generator/agent.md new file mode 100644 index 00000000..a386b13a --- /dev/null +++ b/kits/sql-query-generator/agent.md @@ -0,0 +1,19 @@ +# SQL Query Generator Agent + +## Overview +This agent converts natural language questions into optimized, read-only SQL queries. Users provide their database schema (as CREATE TABLE statements) and ask questions in plain English. The agent returns a well-structured SQL SELECT query along with an explanation, the tables used, any assumptions made, and a confidence score. + +## Architecture +The agent uses a single Lamatic Flow with three nodes: +1. **API Request** — receives the database schema and question via GraphQL +2. **Generate Text (LLM)** — processes the inputs using a system prompt tuned for SQL generation +3. **API Response** — returns the generated SQL as a JSON string + +## Key Design Decisions +- **Read-only queries only** — the agent is explicitly instructed to never generate INSERT, UPDATE, DELETE, DROP, or ALTER statements, making it safe for production use +- **Structured JSON output** — the response includes sql, explanation, tables_used, assumptions, and confidence fields for easy frontend parsing +- **Cross-database compatibility** — queries target standard SQL that works across PostgreSQL, MySQL, and SQLite +- **Explicit JOINs** — the agent prefers explicit JOIN syntax over implicit joins for readability + +## Flows +1. `sql-query-generator` — the single flow that handles schema parsing, SQL generation, and response formatting diff --git a/kits/sql-query-generator/apps/.env.example b/kits/sql-query-generator/apps/.env.example new file mode 100644 index 00000000..2db88fab --- /dev/null +++ b/kits/sql-query-generator/apps/.env.example @@ -0,0 +1,4 @@ +SQL_QUERY_GENERATOR_FLOW_ID = "YOUR_FLOW_ID" +LAMATIC_API_URL = "YOUR_API_ENDPOINT" +LAMATIC_PROJECT_ID = "YOUR_PROJECT_ID" +LAMATIC_API_KEY = "YOUR_API_KEY" diff --git a/kits/sql-query-generator/apps/.gitignore b/kits/sql-query-generator/apps/.gitignore new file mode 100644 index 00000000..a659badb --- /dev/null +++ b/kits/sql-query-generator/apps/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +.next/ +.env +.env.local +*.tsbuildinfo +next-env.d.ts diff --git a/kits/sql-query-generator/apps/actions/orchestrate.ts b/kits/sql-query-generator/apps/actions/orchestrate.ts new file mode 100644 index 00000000..22cf1bfd --- /dev/null +++ b/kits/sql-query-generator/apps/actions/orchestrate.ts @@ -0,0 +1,70 @@ +"use server"; + +import lamaticClient from "@/lib/lamatic-client"; + +interface SQLGeneratorResult { + sql: string | null; + explanation: string; + tables_used: string[]; + assumptions: string | null; + confidence: "high" | "medium" | "low"; +} + +interface GenerateQueryResponse { + success: boolean; + data?: SQLGeneratorResult; + error?: string; +} + +function parseResponse(raw: string): SQLGeneratorResult { + let cleaned = raw.trim(); + if (cleaned.startsWith("```json")) { + cleaned = cleaned.slice(7); + } else if (cleaned.startsWith("```")) { + cleaned = cleaned.slice(3); + } + if (cleaned.endsWith("```")) { + cleaned = cleaned.slice(0, -3); + } + cleaned = cleaned.trim(); + return JSON.parse(cleaned); +} + +export async function generateQuery( + schema: string, + question: string +): Promise { + try { + if (!schema.trim()) { + return { success: false, error: "Please provide a database schema." }; + } + if (!question.trim()) { + return { success: false, error: "Please provide a question." }; + } + + const flowId = process.env.SQL_QUERY_GENERATOR_FLOW_ID; + if (!flowId) { + return { success: false, error: "Flow ID is not configured." }; + } + + const response = await lamaticClient.executeFlow(flowId, { + schema: schema, + question: question, + }); + + const result = (response as any)?.result?.result; + + if (!result) { + return { success: false, error: "No response received from the agent." }; + } + + const parsed = parseResponse(result); + return { success: true, data: parsed }; + } catch (err) { + console.error("SQL generation error:", err); + return { + success: false, + error: err instanceof Error ? err.message : "Something went wrong.", + }; + } +} \ No newline at end of file diff --git a/kits/sql-query-generator/apps/app/globals.css b/kits/sql-query-generator/apps/app/globals.css new file mode 100644 index 00000000..f1d8c73c --- /dev/null +++ b/kits/sql-query-generator/apps/app/globals.css @@ -0,0 +1 @@ +@import "tailwindcss"; diff --git a/kits/sql-query-generator/apps/app/layout.tsx b/kits/sql-query-generator/apps/app/layout.tsx new file mode 100644 index 00000000..46db9b57 --- /dev/null +++ b/kits/sql-query-generator/apps/app/layout.tsx @@ -0,0 +1,20 @@ +import type { Metadata } from "next"; +import "./globals.css"; + +export const metadata: Metadata = { + title: "SQL Query Generator", + description: + "Convert natural language questions into optimized SQL queries using AI.", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/kits/sql-query-generator/apps/app/page.tsx b/kits/sql-query-generator/apps/app/page.tsx new file mode 100644 index 00000000..a80eff50 --- /dev/null +++ b/kits/sql-query-generator/apps/app/page.tsx @@ -0,0 +1,236 @@ +"use client"; + +import { useState } from "react"; +import { generateQuery } from "@/actions/orchestrate"; + +interface QueryResult { + sql: string | null; + explanation: string; + tables_used: string[]; + assumptions: string | null; + confidence: "high" | "medium" | "low"; +} + +const SAMPLE_SCHEMA = `CREATE TABLE users ( + id INT PRIMARY KEY, + name VARCHAR(100), + email VARCHAR(100), + created_at DATE +); + +CREATE TABLE orders ( + id INT PRIMARY KEY, + user_id INT, + amount DECIMAL(10,2), + status VARCHAR(20), + order_date DATE +); + +CREATE TABLE products ( + id INT PRIMARY KEY, + name VARCHAR(100), + price DECIMAL(10,2), + category VARCHAR(50) +);`; + +const SAMPLE_QUESTION = + "Find the top 5 users who spent the most money on completed orders"; + +export default function Home() { + const [schema, setSchema] = useState(""); + const [question, setQuestion] = useState(""); + const [result, setResult] = useState(null); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(false); + + const handleSubmit = async () => { + setLoading(true); + setError(""); + setResult(null); + + const response = await generateQuery(schema, question); + + if (response.success && response.data) { + setResult(response.data); + } else { + setError(response.error || "Something went wrong."); + } + + setLoading(false); + }; + + const loadSample = () => { + setSchema(SAMPLE_SCHEMA); + setQuestion(SAMPLE_QUESTION); + setResult(null); + setError(""); + }; + + const confidenceColor = (level: string) => { + if (level === "high") return "bg-green-100 text-green-800"; + if (level === "medium") return "bg-yellow-100 text-yellow-800"; + return "bg-red-100 text-red-800"; + }; + + return ( +
+
+ {/* Header */} +
+

+ SQL Query Generator +

+

+ Paste your database schema, ask a question in plain English, and get + an optimized SQL query. +

+
+ + {/* Input Section */} +
+
+ + +
+