Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions kits/sql-query-explainer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.env
.env.local
node_modules/
*.log
.DS_Store
59 changes: 59 additions & 0 deletions kits/sql-query-explainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# SQL Query Explainer

## About This Flow

This workflow accepts any SQL query and returns a **structured JSON explanation** — no database connection required. Useful for developers, data engineers, and analysts who need to quickly understand unfamiliar queries, document SQL code, or surface performance concerns before a query reaches production.

This flow includes **3 nodes**: graphqlNode → LLMNode → graphqlResponseNode.

## What It Returns

The API response contains an `explanation` field with a JSON object:

```json
{
"summary": "Plain-English description of what the query does.",
"dialect_hint": "PostgreSQL",
"clauses": [
{ "clause": "SELECT", "explanation": "Retrieves user ID, name, and order count." }
],
"performance_concerns": ["LEFT JOIN on large table without index on user_id."],
"optimisation_suggestions": ["Add index on orders.user_id."],
"example_output_description": "Up to 20 rows with user ID, name, order count sorted descending."
}
Comment on lines +11 to +23
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Mission clarity: describe the response as JSON text, not a parsed object.

The flow forwards generatedResponse directly into explanation, so the API emits JSON text unless another step parses it. Update the wording/example so consumers know they need to parse the field.

Suggested wording tweak
- The API response contains an `explanation` field with a JSON object:
+ The API response contains an `explanation` field containing JSON text for the explanation object:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The API response contains an `explanation` field with a JSON object:
```json
{
"summary": "Plain-English description of what the query does.",
"dialect_hint": "PostgreSQL",
"clauses": [
{ "clause": "SELECT", "explanation": "Retrieves user ID, name, and order count." }
],
"performance_concerns": ["LEFT JOIN on large table without index on user_id."],
"optimisation_suggestions": ["Add index on orders.user_id."],
"example_output_description": "Up to 20 rows with user ID, name, order count sorted descending."
}
The API response contains an `explanation` field containing JSON text for the explanation object:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@kits/sql-query-explainer/README.md` around lines 11 - 23, The README
currently implies the API returns a parsed object but the code forwards
generatedResponse directly into the explanation field, so the API actually emits
JSON text; update the README wording and example to clearly state that
explanation is a JSON string (text) that clients must JSON.parse, and change the
example block to show the field as JSON text (or show parsing example) so
consumers know to parse the explanation value generatedResponse into an object
before reading summary, clauses, performance_concerns, optimisation_suggestions,
dialect_hint, and example_output_description.

```

## Example Input

```json
{
"query": "SELECT u.id, u.name, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.created_at >= '2024-01-01' GROUP BY u.id, u.name HAVING COUNT(o.id) > 5 ORDER BY order_count DESC LIMIT 20;"
}
```

## Use Cases

- **Code Review** — Auto-annotate SQL changes with plain-English descriptions and performance flags.
- **Developer Onboarding** — Help new engineers understand existing queries without DBA review.
- **SQL Education** — Build learning tools that explain queries clause by clause.
- **Data Documentation** — Generate consistent documentation for complex analytical queries.
- **Pre-Production Checks** — Surface SQL anti-patterns before queries run.

## Prerequisites

- A Lamatic.ai account ([lamatic.ai](https://lamatic.ai))
- An LLM provider connected in your Lamatic workspace

## Usage

1. Import this template into your Lamatic workspace
2. Connect your LLM provider credentials
3. Deploy the flow
4. Send a POST request with a `query` field containing your SQL
Comment on lines +42 to +52
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Mission requirement: add an environment-variables section.

The README currently covers setup and usage, but it never states whether the kit needs any env vars or explicitly that none are required. That leaves the kit documentation incomplete for contributors. As per coding guidelines, kits/**/README.md: Every kit must have a README.md that documents setup, environment variables, and usage.

Suggested addition
 ## Prerequisites
 
 - A Lamatic.ai account
 - An LLM provider connected in your Lamatic workspace
+
+## Environment Variables
+
+- None required. This kit uses the connected LLM provider configured in Lamatic.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Prerequisites
- A Lamatic.ai account ([lamatic.ai](https://lamatic.ai))
- An LLM provider connected in your Lamatic workspace
## Usage
1. Import this template into your Lamatic workspace
2. Connect your LLM provider credentials
3. Deploy the flow
4. Send a POST request with a `query` field containing your SQL
## Prerequisites
- A Lamatic.ai account ([lamatic.ai](https://lamatic.ai))
- An LLM provider connected in your Lamatic workspace
## Environment Variables
- None required. This kit uses the connected LLM provider configured in Lamatic.
## Usage
1. Import this template into your Lamatic workspace
2. Connect your LLM provider credentials
3. Deploy the flow
4. Send a POST request with a `query` field containing your SQL
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@kits/sql-query-explainer/README.md` around lines 42 - 52, Add an "Environment
variables" section to the README.md (near the "Prerequisites" and "Usage"
sections) that explicitly documents required env vars for this kit: either list
each variable name, its purpose, and example/default value if any, or state "No
environment variables required" if none are needed; update the README headings
to include "Environment variables" so contributors know where to look.


## Tags

Developer Tools, Generative, Analytics, SQL

---
*Author: Saad Mohammad | saadmd723@gmail.com*
48 changes: 48 additions & 0 deletions kits/sql-query-explainer/agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# SQL Query Explainer

## Overview
This AgentKit template solves the problem of quickly understanding any SQL query — no matter its complexity — without having to run it or ask a colleague. It is implemented as a **single-flow** API-invoked pipeline: an API request triggers an LLM analysis step, and the result is returned as a structured JSON object. The primary caller is a developer tool, internal portal, code review system, or any automation that needs an on-demand "explain this SQL" capability.

---

## Purpose
The goal of this agent is to reduce the time and cognitive overhead required to understand an unfamiliar SQL query. After it runs, the caller receives a compact structured breakdown that captures what the query does, how each clause contributes, what performance risks exist, and how to improve it — without needing to execute the query or consult a DBA.

Operationally, the agent accepts a raw SQL query string (any dialect), passes it to an LLM with a strict JSON-output system prompt, and returns a structured explanation object. This makes it suitable for developer portals, code review automations, SQL learning tools, data engineering onboarding flows, and any system that needs consistent, structured SQL documentation at scale.

Because this kit is a template with a single flow, all behaviour is concentrated in one pipeline. If you extend it (e.g., adding dialect detection, multi-query batching, or storage of past explanations), the existing flow remains the canonical entrypoint for "SQL query → explanation".

## Flows

### SQL Query Explainer

- Trigger
- Invocation: API call via a GraphQL-triggered request node (`graphqlNode`) exposed by the AgentKit runtime.
- Expected input shape:
- A payload containing the `query` field.
- The flow is designed around "SQL in, explanation out"; the GraphQL field name is `query` (string — the raw SQL query to analyse).
- Input notes: Any valid SQL query string is accepted. Multi-statement queries, CTEs, subqueries, window functions, and dialect-specific syntax are all supported. The LLM will do its best to infer the dialect.

- What it does
1. `API Request` (`graphqlNode`)
- Accepts the incoming GraphQL/API request from the caller.
- Validates and surfaces the `query` field to downstream nodes as `{{triggerNode_1.output.query}}`.
2. `Explain Query` (`LLMNode`)
- Runs an LLM analysis with a structured system prompt that instructs the model to return valid JSON only.
- System prompt (`sql-query-explainer_explain-query_system.md`) defines the output schema and rules.
- User prompt (`sql-query-explainer_explain-query_user.md`) injects the raw query as `{{triggerNode_1.output.query}}`.
- Produces `generatedResponse` — a JSON string containing the full explanation object.
3. `API Response` (`graphqlResponseNode`)
- Formats and returns the explanation to the caller as the `explanation` field in the API response.

- When to use this flow
- Use when a developer needs to quickly understand an unfamiliar SQL query.
- Use in a code review pipeline to auto-generate SQL change descriptions.
- Use in a developer onboarding tool to help new engineers understand existing queries.
- Use in a data engineering portal to document complex analytical queries.
- Use in a SQL learning application to explain queries step by step.

- When not to use this flow
- Do not use when you need to execute the query and retrieve actual data.
- Do not use for extremely large queries (200+ lines) without chunking — LLM context windows may be strained.
- Do not use as a replacement for database-native EXPLAIN / EXPLAIN ANALYZE plans when diagnosing real execution bottlenecks.
65 changes: 65 additions & 0 deletions kits/sql-query-explainer/flows/sql-query-explainer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Flow: sql-query-explainer
// Accepts a raw SQL query and returns a structured JSON explanation.

export const meta = {
"name": "SQL Query Explainer",
"description": "Accepts any SQL query and returns a structured JSON explanation: plain-English summary, clause breakdown, performance concerns, and optimisation suggestions.",
"tags": ["Developer Tools", "Generative", "Analytics"],
"testInput": {
"query": "SELECT u.id, u.name, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.created_at >= '2024-01-01' GROUP BY u.id, u.name HAVING COUNT(o.id) > 5 ORDER BY order_count DESC LIMIT 20;"
},
"githubUrl": "",
"documentationUrl": "",
"deployUrl": "https://studio.lamatic.ai/template/sql-query-explainer",
};

export const nodes = [
{
"id": "triggerNode_1",
"type": "graphqlNode",
"label": "API Request",
"data": {
"description": "Accepts the incoming API request. Expects a query string field containing the SQL to explain.",
"inputs": {
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "The raw SQL query string to explain." }
},
"required": ["query"]
}
}
}
},
{
"id": "LLMNode_1",
"type": "LLMNode",
"label": "Explain Query",
"data": {
"description": "Sends the SQL query to the LLM with a structured system prompt. Returns JSON with summary, clauses, performance concerns, and optimisation suggestions.",
"inputs": {
"systemPrompt": "@prompts/sql-query-explainer_explain-query_system.md",
"userPrompt": "@prompts/sql-query-explainer_explain-query_user.md",
"modelConfig": "@model-configs/sql-query-explainer_explain-query.ts"
},
"outputs": { "generatedResponse": "string" }
}
},
{
"id": "responseNode_1",
"type": "graphqlResponseNode",
"label": "API Response",
"data": {
"description": "Returns the structured JSON explanation to the API caller.",
"inputs": {
"response": { "explanation": "{{LLMNode_1.output.generatedResponse}}" }
},
"responseMode": "realtime"
}
}
];

export const edges = [
{ "id": "edge_trigger_to_llm", "source": "triggerNode_1", "target": "LLMNode_1" },
{ "id": "edge_llm_to_response", "source": "LLMNode_1", "target": "responseNode_1" }
];
15 changes: 15 additions & 0 deletions kits/sql-query-explainer/lamatic.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default {
name: "SQL Query Explainer",
description: "This workflow accepts any SQL query (SELECT, INSERT, UPDATE, DELETE, CTEs, window functions, etc.) and returns a plain-English explanation, a clause-by-clause breakdown, a list of potential performance issues, and concrete optimisation suggestions. It is useful for developers learning SQL, onboarding engineers reading unfamiliar queries, and anyone who needs to quickly understand what a query does without running it.",
version: '1.0.0',
type: 'template' as const,
author: {"name":"Saad Mohammad","email":"saadmd723@gmail.com"},
tags: ["developer-tools","sql","generative","analytics"],
steps: [
{ id: "sql-query-explainer", type: 'mandatory' as const }
],
links: {
"deploy": "https://studio.lamatic.ai/template/sql-query-explainer",
"github": "https://github.com/Lamatic/AgentKit/tree/main/kits/sql-query-explainer"
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Model config: Explain Query (LLMNode)
// Flow: sql-query-explainer

export default {
"generativeModelName": "@model-configs/sql-query-explainer_explain-query.ts",
"memories": "@model-configs/sql-query-explainer_explain-query.ts",
"messages": "@model-configs/sql-query-explainer_explain-query.ts"
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
You are an expert SQL analyst and database engineer with deep knowledge of SQL dialects including PostgreSQL, MySQL, SQLite, BigQuery, Snowflake, and SQL Server.

Your job is to analyse a SQL query provided by the user and return a structured, developer-friendly explanation. Your response must always follow this exact JSON structure:

```json
{
"summary": "One or two sentence plain-English description of what the query does.",
"dialect_hint": "The SQL dialect this query appears to target, or 'Standard SQL' if dialect-agnostic.",
"clauses": [
{
"clause": "Name of the SQL clause (e.g. SELECT, FROM, WHERE, GROUP BY, ORDER BY, WITH, JOIN, HAVING, LIMIT)",
"explanation": "Plain-English explanation of what this specific clause does in context."
}
],
"performance_concerns": [
"Description of a potential performance issue, or an empty array if none detected."
],
"optimisation_suggestions": [
"A concrete, actionable optimisation tip, or an empty array if none applicable."
],
"example_output_description": "A brief description of what the result set would look like (columns, rows, shape) if the query ran successfully."
}
```

Rules:
- Always respond with valid JSON only. Do not include markdown code fences or any text outside the JSON object.
- Be precise and concise in each field.
- If the query has syntax errors, still do your best to explain the apparent intent and note the error in `performance_concerns`.
- Do not execute or simulate the query. Only analyse its structure and logic.
- Tailor explanations for a developer audience — avoid overly simplistic language but also avoid unnecessary jargon.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SQL Query:

{{triggerNode_1.output.query}}
Comment on lines +1 to +3
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Mission risk: delimit the SQL before interpolation.

Raw interpolation here mixes user data with prompt instructions, which makes prompt-injection and instruction-smuggling easier. Wrap the query in an explicit fenced block or another delimiter so the model treats it as data.

Suggested fix
 SQL Query:
 
-{{triggerNode_1.output.query}}
+```sql
+{{triggerNode_1.output.query}}
+```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
SQL Query:
{{triggerNode_1.output.query}}
SQL Query:
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@kits/sql-query-explainer/prompts/sql-query-explainer_explain-query_user.md`
around lines 1 - 3, The prompt injects raw user SQL via
{{triggerNode_1.output.query}} without delimiters; wrap the interpolated value
in an explicit fenced block or clear delimiter (e.g., triple backticks or
labeled sql fence) so the model treats it strictly as data rather than
instructions—update the template in sql-query-explainer_explain-query_user.md to
place {{triggerNode_1.output.query}} inside that fenced block (or equivalent
delimiter) and ensure any leading/trailing whitespace is preserved but outside
text of the prompt.

Loading