"use client"; import { useCallback, useState } from "react"; import { Background, BackgroundVariant, Handle, MarkerType, type Node, type NodeProps, type OnInit, Position, ReactFlow, } from "@xyflow/react"; import "@xyflow/react/dist/style.css"; type LaneVariant = "manual" | "ktx"; type AgentNodeData = { variant: "single"; title: string; subtitle: string; }; type IssueNote = { id: number; label: string; }; type ManualSqlNodeData = { variant: "manual"; badge: string; title: string; caption: string; code: string; notes: IssueNote[]; lineIssues: Record; }; type SlQueryNodeData = { variant: "slQuery"; badge: string; title: string; caption: string; code: string; }; type EngineNodeData = { variant: "engine"; badge: string; title: string; stages: Array<{ index: number; title: string; detail: string }>; }; type CompiledSqlNodeData = { variant: "compiled"; badge: string; title: string; caption: string; code: string; notes: string[]; }; type WarehouseNodeData = { variant: "warehouse"; title: string; drivers: string[]; }; type AgentNode = Node; type ManualSqlNode = Node; type SlQueryNode = Node; type EngineNode = Node; type CompiledSqlNode = Node; type WarehouseNode = Node; type FlowNode = | AgentNode | ManualSqlNode | SlQueryNode | EngineNode | CompiledSqlNode | WarehouseNode; const CANVAS_W = 1120; const AGENT_W = 380; const AGENT_H = 104; const AGENT_X = (CANVAS_W - AGENT_W) / 2; const AGENT_Y = 16; const LANE_W = 488; const LEFT_LANE_X = 32; const RIGHT_LANE_X = CANVAS_W - LEFT_LANE_X - LANE_W; const LANE_TOP_Y = 248; const SL_QUERY_H = 510; const ENGINE_H = 380; const COMPILED_H = 1380; const RIGHT_GAP = 24; const RIGHT_LANE_TOTAL = SL_QUERY_H + RIGHT_GAP + ENGINE_H + RIGHT_GAP + COMPILED_H; const MANUAL_SQL_H = 840; const LANES_BOTTOM_Y = LANE_TOP_Y + Math.max(MANUAL_SQL_H, RIGHT_LANE_TOTAL); const SL_QUERY_Y = LANE_TOP_Y; const ENGINE_Y = SL_QUERY_Y + SL_QUERY_H + RIGHT_GAP; const COMPILED_Y = ENGINE_Y + ENGINE_H + RIGHT_GAP; const WAREHOUSE_W = 304; const WAREHOUSE_H = 92; const WAREHOUSE_X = (CANVAS_W - WAREHOUSE_W) / 2; const WAREHOUSE_Y = LANES_BOTTOM_Y + 56; const MANUAL_STROKE = "#94a3b8"; const KTX_STROKE = "#0891b2"; const FIT_VIEW_OPTIONS = { padding: 0.05 }; const agent: AgentNode = { id: "agent", type: "agent", position: { x: AGENT_X, y: AGENT_Y }, data: { variant: "single", title: "Analytics agent", subtitle: "Asks: monthly net revenue and open tickets per segment, high-value orders only, no test customers", }, draggable: false, selectable: false, }; const manualSql: ManualSqlNode = { id: "manual-sql", type: "manualSql", position: { x: LEFT_LANE_X, y: LANE_TOP_Y }, data: { variant: "manual", badge: "Without KTX", title: "Agent writes the SQL", caption: "Stitches four tables, mixes grains, and ships numbers that won't match the dashboard.", code: `-- agent stitches four tables, mixes facts, -- and ships numbers that won't match the dashboard SELECT c.segment, DATE_TRUNC('month', o.created_at) AS month, SUM(o.amount) - SUM(r.amount) AS net_revenue, COUNT(t.id) AS open_tickets FROM customers c LEFT JOIN orders o ON o.customer_id = c.id LEFT JOIN refunds r ON r.order_id = o.id LEFT JOIN tickets t ON t.customer_id = c.id WHERE c.is_test = false AND o.amount >= 100 AND t.status = 'open' -- turns LEFT JOIN into INNER GROUP BY c.segment, DATE_TRUNC('month', o.created_at) ORDER BY month, c.segment LIMIT 1000; -- chasm trap: orders rows multiply by tickets and refunds -- net_revenue and open_tickets are both inflated -- DATE_TRUNC syntax breaks on BigQuery`, notes: [ { id: 1, label: "Re-stitches a 4-way join on every question" }, { id: 2, label: "Reinvents net_revenue and the high-value rule" }, { id: 3, label: "Hides a chasm trap across three facts" }, { id: 4, label: "Filters a LEFT JOIN target in WHERE" }, { id: 5, label: "Hardcodes one warehouse's date functions" }, ], lineIssues: { 5: [5], 6: [2, 3], 7: [3], 8: [1], 9: [1], 10: [1], 11: [1], 12: [1], 13: [1], 14: [1], 17: [2], 18: [4], 21: [5], 27: [3], 28: [3], 29: [5], }, }, draggable: false, selectable: false, }; const slQuery: SlQueryNode = { id: "sl-query", type: "slQuery", position: { x: RIGHT_LANE_X, y: SL_QUERY_Y }, data: { variant: "slQuery", badge: "With KTX", title: "Agent sends a Semantic Query", caption: "Names the measures, dimensions, segments, and filters it wants. No SQL, no joins.", code: `{ "measures": [ "orders.revenue", "refunds.amount", "tickets.open_count", { "name": "net_revenue", "expr": "orders.revenue - refunds.amount" } ], "dimensions": [ "customers.segment", { "field": "orders.created_at", "granularity": "month" } ], "segments": ["orders.high_value"], "filters": ["customers.is_test = false"], "limit": 1000 }`, }, draggable: false, selectable: false, }; const engine: EngineNode = { id: "engine", type: "engine", position: { x: RIGHT_LANE_X, y: ENGINE_Y }, data: { variant: "engine", badge: "Semantic-layer engine", title: "Plans the query against the reviewed graph", stages: [ { index: 1, title: "Resolve refs", detail: "qualify columns, look up measure formulas", }, { index: 2, title: "Build join tree", detail: "Dijkstra over typed edges from an anchor source", }, { index: 3, title: "Detect fan-out", detail: "group measures by source, flag chasm traps", }, { index: 4, title: "Localize aggregation", detail: "pre-aggregate each fact as its own CTE", }, { index: 5, title: "Transpile dialect", detail: "emit Postgres-shaped SQL, then target dialect", }, ], }, draggable: false, selectable: false, }; const compiledSql: CompiledSqlNode = { id: "compiled-sql", type: "compiledSql", position: { x: RIGHT_LANE_X, y: COMPILED_Y }, data: { variant: "compiled", badge: "Generated SQL", title: "KTX returns dialect-correct SQL", caption: "Pre-aggregates each fact at its own grain, then joins back on the shared dimension.", code: `WITH orders_agg AS ( SELECT customer_id, DATE_TRUNC('month', created_at) AS month, SUM(amount) AS revenue FROM public.orders WHERE amount >= 100 GROUP BY customer_id, DATE_TRUNC('month', created_at) ), refunds_agg AS ( SELECT o.customer_id, DATE_TRUNC('month', o.created_at) AS month, SUM(r.amount) AS refund_amount FROM public.refunds r JOIN public.orders o ON o.id = r.order_id WHERE o.amount >= 100 GROUP BY o.customer_id, DATE_TRUNC('month', o.created_at) ), tickets_agg AS ( SELECT customer_id, DATE_TRUNC('month', opened_at) AS month, COUNT(*) AS open_count FROM public.tickets WHERE status = 'open' GROUP BY customer_id, DATE_TRUNC('month', opened_at) ) SELECT c.segment, o.month, SUM(o.revenue - COALESCE(r.refund_amount, 0)) AS net_revenue, SUM(o.revenue) AS revenue, SUM(r.refund_amount) AS refund_amount, SUM(COALESCE(t.open_count, 0)) AS open_tickets FROM public.customers c JOIN orders_agg o ON o.customer_id = c.id LEFT JOIN refunds_agg r ON r.customer_id = c.id AND r.month = o.month LEFT JOIN tickets_agg t ON t.customer_id = c.id AND t.month = o.month WHERE c.is_test = false GROUP BY c.segment, o.month ORDER BY o.month, c.segment LIMIT 1000;`, notes: [ "Walks the reviewed join graph automatically", "Uses the canonical net_revenue formula", "Pre-aggregates each fact to avoid the chasm trap", "Keeps LEFT JOIN filters on the dimension source", "Transpiles DATE_TRUNC to the target dialect", ], }, draggable: false, selectable: false, }; const warehouse: WarehouseNode = { id: "warehouse", type: "warehouse", position: { x: WAREHOUSE_X, y: WAREHOUSE_Y }, data: { variant: "warehouse", title: "Warehouse", drivers: ["PostgreSQL", "Snowflake", "BigQuery"], }, draggable: false, selectable: false, }; const nodes: FlowNode[] = [ agent, manualSql, slQuery, engine, compiledSql, warehouse, ]; const arrowMarker = (color: string) => ({ type: MarkerType.ArrowClosed, color, width: 16, height: 16, }); const edges = [ { id: "agent-manual", source: "agent", target: "manual-sql", type: "default" as const, label: "writes raw SQL", labelBgPadding: [6, 3] as [number, number], labelBgBorderRadius: 4, labelStyle: { fontSize: 12, fontWeight: 500, fill: "var(--color-fd-muted-foreground)", }, labelBgStyle: { fill: "var(--color-fd-background)", stroke: "var(--color-fd-border)", strokeWidth: 1, }, style: { stroke: MANUAL_STROKE, strokeWidth: 1.5, strokeDasharray: "5 4", }, markerEnd: arrowMarker(MANUAL_STROKE), }, { id: "manual-warehouse", source: "manual-sql", target: "warehouse", targetHandle: "warehouse-manual", type: "default" as const, style: { stroke: MANUAL_STROKE, strokeWidth: 1.5, strokeDasharray: "5 4", }, markerEnd: arrowMarker(MANUAL_STROKE), }, { id: "agent-slquery", source: "agent", target: "sl-query", type: "default" as const, label: "sends Semantic Query", labelBgPadding: [6, 3] as [number, number], labelBgBorderRadius: 4, labelStyle: { fontSize: 12, fontWeight: 600, fill: KTX_STROKE, }, labelBgStyle: { fill: "var(--color-fd-background)", stroke: "var(--color-fd-border)", strokeWidth: 1, }, style: { stroke: KTX_STROKE, strokeWidth: 1.75 }, markerEnd: arrowMarker(KTX_STROKE), }, { id: "slquery-engine", source: "sl-query", target: "engine", type: "straight" as const, style: { stroke: KTX_STROKE, strokeWidth: 1.75 }, markerEnd: arrowMarker(KTX_STROKE), }, { id: "engine-compiled", source: "engine", target: "compiled-sql", type: "straight" as const, style: { stroke: KTX_STROKE, strokeWidth: 1.75 }, markerEnd: arrowMarker(KTX_STROKE), }, { id: "compiled-warehouse", source: "compiled-sql", target: "warehouse", targetHandle: "warehouse-compiled", type: "straight" as const, style: { stroke: KTX_STROKE, strokeWidth: 1.75 }, markerEnd: arrowMarker(KTX_STROKE), }, ]; type FlowEdge = (typeof edges)[number]; function AgentNodeView({ data }: NodeProps) { return (

{data.title}

{data.subtitle}

); } function LaneBadge({ variant, children, }: { variant: LaneVariant; children: React.ReactNode; }) { const cls = variant === "manual" ? "border-slate-300 bg-slate-100 text-slate-700 dark:border-slate-600/60 dark:bg-slate-700/40 dark:text-slate-200" : "border-cyan-300/70 bg-cyan-50 text-cyan-800 dark:border-cyan-400/40 dark:bg-cyan-400/15 dark:text-cyan-100"; return ( {children} ); } const JSON_TOKEN_PATTERN = /"(?:\\.|[^"\\])*"|-?\b\d+(?:\.\d+)?\b|\b(?:true|false|null)\b|[{}[\],:]/g; const SQL_TOKEN_PATTERN = /--[^\n]*|'(?:''|[^'])*'|\b\d+(?:\.\d+)?\b|\b(?:select|from|join|left|right|inner|outer|on|where|group|by|order|limit|as|sum|count|coalesce|date_trunc|case|when|then|else|end|and|or|is|not|null|false|true|with|having|over|partition)\b|[(),.;=*<>+-]/gi; const SQL_FUNCTIONS = new Set(["sum", "count", "coalesce", "date_trunc"]); function highlightJson(code: string) { const parts = []; let lastIndex = 0; let tokenIndex = 0; for (const match of code.matchAll(JSON_TOKEN_PATTERN)) { const token = match[0]; const index = match.index ?? 0; if (index > lastIndex) parts.push(code.slice(lastIndex, index)); const nextText = code.slice(index + token.length); const className = token.startsWith('"') ? /^\s*:/.test(nextText) ? "syntax-json-key" : "syntax-string" : /^-?\d/.test(token) ? "syntax-number" : /^(true|false|null)$/.test(token) ? "syntax-constant" : "syntax-punctuation"; parts.push( {token} , ); lastIndex = index + token.length; tokenIndex += 1; } if (lastIndex < code.length) parts.push(code.slice(lastIndex)); return parts; } function highlightSql(code: string) { const parts = []; let lastIndex = 0; let tokenIndex = 0; for (const match of code.matchAll(SQL_TOKEN_PATTERN)) { const token = match[0]; const index = match.index ?? 0; if (index > lastIndex) parts.push(code.slice(lastIndex, index)); const lowerToken = token.toLowerCase(); const className = token.startsWith("--") ? "syntax-comment" : token.startsWith("'") ? "syntax-string" : /^\d/.test(token) ? "syntax-number" : SQL_FUNCTIONS.has(lowerToken) ? "syntax-function" : /^[a-z_]+$/i.test(token) ? "syntax-keyword" : "syntax-punctuation"; parts.push( {token} , ); lastIndex = index + token.length; tokenIndex += 1; } if (lastIndex < code.length) parts.push(code.slice(lastIndex)); return parts; } function highlightCode(language: string, code: string) { if (language === "json") return highlightJson(code); if (language === "sql") return highlightSql(code); return code; } function CodeBlock({ language, code, tone, }: { language: string; code: string; tone: "manual" | "slQuery" | "compiled"; }) { const toneClass = tone === "manual" ? "text-slate-600 dark:text-slate-300" : tone === "slQuery" ? "text-fd-primary" : "text-fd-primary/90"; const highlightedCode = highlightCode(language, code); return (
{language} {tone === "compiled" ? "ktx-compiled" : "agent-authored"}
        {highlightedCode}
      
); } function AnnotatedSqlBlock({ code, lineIssues, activeIssue, onIssueEnter, onIssueLeave, }: { code: string; lineIssues: Record; activeIssue: number | null; onIssueEnter: (n: number) => void; onIssueLeave: () => void; }) { const lines = code.split("\n"); return (
sql agent-authored
        {lines.map((line, idx) => {
          const issues = lineIssues[idx] ?? [];
          const hasIssue = issues.length > 0;
          const dim =
            activeIssue !== null && !issues.includes(activeIssue);
          const active =
            activeIssue !== null && issues.includes(activeIssue);
          const classes = [
            "sl-sql-line",
            hasIssue ? "is-issue" : "",
            active ? "is-active" : "",
            dim ? "is-dim" : "",
          ]
            .filter(Boolean)
            .join(" ");
          return (
            
{issues.map((n) => ( ))} {line.length ? highlightSql(line) : " "}
); })}
); } function ManualSqlNodeView({ data }: NodeProps) { const [activeIssue, setActiveIssue] = useState(null); const clearActive = useCallback(() => setActiveIssue(null), []); return (
{data.badge}

{data.title}

{data.caption}

    {data.notes.map((note) => { const dim = activeIssue !== null && activeIssue !== note.id; const active = activeIssue === note.id; return (
  • setActiveIssue(note.id)} onMouseLeave={clearActive} onFocus={() => setActiveIssue(note.id)} onBlur={clearActive} tabIndex={0} > {note.label}
  • ); })}
); } function SlQueryNodeView({ data }: NodeProps) { return (
{data.badge}

{data.title}

{data.caption}

); } function EngineNodeView({ data }: NodeProps) { return (
); } function CompiledSqlNodeView({ data }: NodeProps) { return (
{data.badge}

{data.title}

{data.caption}

    {data.notes.map((note) => (
  • ))}
); } function WarehouseNodeView({ data }: NodeProps) { return (

{data.title}

{data.drivers.join(" • ")}

); } const nodeTypes = { agent: AgentNodeView, manualSql: ManualSqlNodeView, slQuery: SlQueryNodeView, engine: EngineNodeView, compiledSql: CompiledSqlNodeView, warehouse: WarehouseNodeView, }; export function SemanticLayerFlow() { const [minZoom, setMinZoom] = useState(0.2); const handleFlowInit = useCallback>((instance) => { requestAnimationFrame(() => { void instance.fitView(FIT_VIEW_OPTIONS).then(() => { setMinZoom(instance.getZoom()); }); }); }, []); return (
Imperative vs declarative

Same answer, two contracts

On the left, the agent works imperatively: chooses tables, writes joins, picks the grain, and remembers each warehouse's dialect. On the right, the agent only declares what it wants. KTX handles every how.

Drag to pan • ⌘/Ctrl + scroll to zoom
); }