Transform data questions into AI-driven SQL queries through conversational intelligence.
Upload data files (Excel, CSV) β Ask questions in English β Get SQL results + AI insights. No SQL knowledge required.
Key Features:
- π― Natural language query interface
- π Auto schema detection & metadata generation
- π Multi-turn conversations with context awareness
- β Smart clarification for ambiguous queries
- π¬ LLM-powered result summarization
- π Multi-tenant with Clerk auth
User Query β FastAPI Backend β LangGraph Workflow β DuckDB SQL Execution β Gemini Insights β Response
1. File Upload β Convert to Parquet β Generate Schema (DuckDB + LLM)
2. User Query β LangGraph State Machine β Intelligent Routing
3. Planner LLM β Generate Execution Plan (tables, filters, aggregations)
4. Execute SQL β Generate Insights β Return to User
8 Nodes in Intelligent Sequence:
| Node | Purpose | Decision |
|---|---|---|
| Input | Validate query | β Planner |
| Planner β | LLM generates SQL plan | Router decides next step |
| Router | Conditional branching | 5 possible routes |
| Clarify | Ask user questions | β END |
| Schema | Fetch table details | β Planner (loop) |
| Preprocess | Data transformations | β SQL Executor |
| SQL Executor | Execute on DuckDB | β Output |
| Output | Format results + insights | β END |
if plan.needs_clarification:
β user_clarification (ask user)
elif plan.metadata_requests:
β schema_info (fetch + replan)
elif plan.preprocessing_operations:
β preprocessing (clean data)
elif plan.execution_mode == "sql":
β sql_executor (execute)
else:
β output (direct response){
"tables": ["sales"],
"filters": ["date >= '2025-10-01'"],
"operations": ["AVG(amount)"],
"group_by": ["category"],
"preprocessing_operations": [
{"type": "fill_nulls", "column": "amount", "method": "mean"}
],
"execution_mode": "sql"
}backend/ # FastAPI + LangGraph
βββ main.py # Endpoints, session management
βββ data_ingestion/
β βββ graph_builder.py # Parquet conversion, schema generation
βββ llm/
β βββ plan_generator.py # β LangGraph workflow (8 nodes)
β βββ interpretor.py # SQL execution
β βββ llm_tracker.py # LLM analytics
βββ utils/ # Rate limiting, DB, cloud storage
my-app/ # Next.js Frontend
βββ app/
β βββ page.tsx # Landing page
β βββ chat/ # Query interface
β βββ upload-file/ # File upload
β βββ api/ # Backend routes
βββ components/ # UI components
Backend: FastAPI, LangGraph 1.0, Gemini API, DuckDB, PostgreSQL, Supabase
Frontend: Next.js 16, React 19, TypeScript, Tailwind CSS, Clerk auth
cd backend
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# .env
GOOGLE_API_KEY=your_key
DATABASE_URL=postgresql://...
Supabase _URL=Supabase ://...
uvicorn main:app --reload --port 8000cd my-app
npm install
# .env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_key
NEXT_PUBLIC_API_URL=http://localhost:8000
npm run dev # http://localhost:3000User asks: "Average revenue by region in Q4?"
-
Planner Node (LLM) β Understands intent
- Tables:
[sales] - Filters:
[date BETWEEN '2025-10-01' AND '2025-12-31'] - Operations:
[AVG(revenue)] - Group:
[region]
- Tables:
-
Router β
execution_mode = "sql"β Routes to SQL Executo -
SQL Executor
SELECT region, AVG(revenue) FROM sales WHERE date BETWEEN '2025-10-01' AND '2025-12-31' GROUP BY region
-
Output Node β Gemini LLM converts results to insights
- "North leads with $2,450 avg (40% higher than West)..."
-
Return β Results + Insights + Save to session history
If query is ambiguous:
- Planner detects ambiguity β
needs_clarification = True - Router β Clarification Node
- Clarification Node β Sends question to user
- User responds β Context appended β Planner replans
Example:
System: "Define 'recent' - last week or month?"
User: "Last 30 days"
β Replans with clarification context
- Clerk authentication
- All queries filtered by
user_id+data_source_id - Per-datasource session isolation
- Secure file storage (Supabase )
- Parquet files - 10x faster than CSV
- DuckDB - In-process SQL (no latency)
- Row limiting - Schema on 10K rows max
- Rate limiting - ~50 LLM calls/min
- Connection reuse - Avoid repeated loads
1. Upload File (Excel/CSV)
β
2. Convert to Parquet (memory-efficient)
β
3. Build Schema via DuckDB
- Detect types
- Normalize columns
- Sample rows
β
4. Generate Metadata (LLM)
- Table summaries
- Relationship detection
β
5. Store
- Parquet β Supabase
- Metadata β PostgreSQL
Files: POST /upload_and_process
Queries: POST /query, POST /continue_conversation, POST /clarify
Sessions: POST /save_session
- SQL validation before execution
- Type coercion (auto-convert strings to numbers)
- NULL handling via preprocessing
- Missing column detection β requests schema
- Failed queries β retry with corrections
- Ambiguous queries β ask user
- Multi-step joins with relationship inference
- Chart/visualization generation
- Scheduled queries & alerts
- Advanced caching
- Federated queries (multiple datasources)
- Explainability reports
LLM Tracking (llm_tracker.py):
- Calls per query
- Token usage
- Latency
- Cost estimation
- Create feature branch:
git checkout -b feature/your-feature - Make changes
- Submit PR
Built with β€οΈ using LangGraph, DuckDB, and Gemini API