@sqlrooms/vega
Vega-Lite chart components and AI chart tool integration for SQLRooms.
Installation
npm install @sqlrooms/vega @sqlrooms/duckdb @sqlrooms/uiMain exports
VegaLiteChart(simple + compound component API)createVegaChartTool()for AI tool workflowscreateChartImageForMarkdownTool()for AI-generated Markdown document image assetsVegaChartToolResult- editor utilities/hooks (
useVegaChartEditor,useVegaEditorContext)
Quick start (simple chart)
import {VegaLiteChart} from '@sqlrooms/vega';
export function SalesChart() {
return (
<VegaLiteChart
sqlQuery="SELECT category, SUM(amount) AS total FROM sales GROUP BY category"
spec={{
mark: 'bar',
encoding: {
x: {field: 'category', type: 'nominal'},
y: {field: 'total', type: 'quantitative'},
},
}}
aspectRatio={16 / 9}
/>
);
}Compound component API (editable chart workflow)
import {VegaLiteChart, type VisualizationSpec} from '@sqlrooms/vega';
const initialSpec: VisualizationSpec = {
mark: 'line',
encoding: {
x: {field: 'date', type: 'temporal'},
y: {field: 'value', type: 'quantitative'},
},
};
export function CompoundVegaChart() {
return (
<VegaLiteChart.Container
spec={initialSpec}
sqlQuery="SELECT date, value FROM metrics"
editable
onSpecChange={(spec) => console.log('next spec', spec)}
onSqlChange={(sql) => console.log('next sql', sql)}
>
<VegaLiteChart.Actions />
<VegaLiteChart.Chart />
<VegaLiteChart.SpecEditor />
<VegaLiteChart.SqlEditor />
</VegaLiteChart.Container>
);
}AI integration (createVegaChartTool)
import {
createAiSlice,
createDefaultAiInstructions,
createDefaultAiTools,
} from '@sqlrooms/ai';
import {
createVegaChartTool,
VegaChartToolResult,
type VegaChartToolResultProps,
} from '@sqlrooms/vega';
// inside your createRoomStore composer
createAiSlice({
tools: {
...createDefaultAiTools(store),
chart: createVegaChartTool({
editable: true,
editorMode: 'both',
}),
},
getInstructions: () => createDefaultAiInstructions(store),
})(set, get, store);createVegaChartTool constructor options:
editable: whether users can edit SQL/spec in the chart UIeditorMode: which editors to render ('none' | 'sql' | 'vega' | 'both')
AI chart result sizing
VegaChartToolResult retains its default 16:9 layout when no sizing props are provided. Use height="auto" to opt into data-driven sizing for category-dense horizontal bar charts:
const CategoryAwareChartResult = (props: VegaChartToolResultProps) => (
<VegaChartToolResult {...props} height="auto" />
);
createAiSlice({
toolRenderers: {
chart: CategoryAwareChartResult,
},
tools: {
chart: createVegaChartTool(),
},
});The automatic policy inspects the parsed Vega-Lite encoding and counts distinct values in the loaded Arrow data. Horizontal bar charts with at least 12 categories use clamp(280, 48 + categoryCount * 22, 800) pixels; other charts continue to use aspectRatio (16:9 by default). Transformed and concatenated multi-view specs also use the aspect ratio because raw Arrow rows do not reflect their rendered data or panel layout. A numeric height fixes the outer chart viewport while preserving responsive width. Applications can also provide getHeight={({spec, arrowTable}) => ...} for a custom sizing policy; returning 'auto' delegates to the built-in category-aware policy.
Sizing is based on loaded query data rather than an LLM-provided row count, so it stays accurate when SQL results or application filters change. The Vega-Lite spec remains responsible for visualization semantics, not React layout.
LLM invocation / Zod schema fields
At runtime, the tool call payload is validated by a Zod schema.
These fields are supplied by the LLM when invoking the tool (not passed into createVegaChartTool(...)):
sqlQuery: SQL used to fetch chart datavegaLiteSpec: Vega-Lite JSON stringreasoning: explanation shown to users for why this chart/spec was chosen
Markdown document image assets
createChartImageForMarkdownTool(store) creates an AI-only companion tool that renders a Vega chart to SVG or PNG, stores it as an asset on a @sqlrooms/documents Markdown artifact, and returns a ready-to-insert Markdown image link such as:
Use this alongside the existing document commands when the assistant needs a portable conversation summary with static chart images instead of live SQL-backed charts.
Chart images default to the light Vega theme with an explicit background so exported Markdown renders predictably in GitHub, Obsidian, PDF exports, and other document surfaces. When the requested static theme matches the current app theme, the background is resolved from the app's Tailwind --background token and written into the SVG/PNG as a concrete color. The tool also accepts renderTheme: "dark" and background for explicit dark/static export requests.
Example apps
- Vega example: https://github.com/sqlrooms/examples/tree/main/vega
- AI example (with chart tool): https://github.com/sqlrooms/examples/tree/main/ai
Interfaces
- VegaChartActionsProps
- VegaChartContextValue
- VegaEditActionProps
- VegaExportActionProps
- VegaChartSizingContext
- VegaEditorState
- VegaEditorActions
- VegaEditorContextValue
- UseVegaChartEditorOptions
- UseVegaChartEditorReturn
Type Aliases
- ChartImageForMarkdownToolParameters
- ChartImageForMarkdownToolOutput
- VegaChartToolParameters
- VegaChartToolOutput
- VegaChartToolOptions
- VegaChartToolResultProps
- VegaChartHeight
- VegaChartHeightResolver
- EditorMode
- OnSpecChange
- OnSqlChange
Variables
- ChartImageForMarkdownToolParameters
- VegaChartActions
- VegaChartToolParameters
- DEFAULT_VEGA_CHART_DESCRIPTION
- VegaEditAction
- VegaExportAction
- VegaCodeMirrorEditor
VegaMonacoEditor- VegaLiteChart
Functions
- createChartImageForMarkdownTool
- useVegaChartContext
- createSqlValidator
- createVegaChartTool
- VegaChartToolResult
- getCategoryAwareVegaChartHeight
- useVegaEditorContext
- useVegaChartEditor
- loadVegaLiteSchema
- getCachedVegaLiteSchema
- preloadVegaLiteSchema
References
ChartImageForMarkdownToolParametersType
Renames and re-exports ChartImageForMarkdownToolParameters