Skip to content

Conversation

@cpsievert
Copy link
Contributor

Summary

This PR integrates ggsql with querychat to enable LLM-generated SQL visualization queries that render as Altair charts. Two new tools (visualize_dashboard, visualize_query) extend the existing tool system across all framework integrations.

New Features

  • Two visualization tools:

    • visualize_dashboard: Creates persistent charts that update when filters change
    • visualize_query: Creates one-off charts from specific SQL queries with VISUALISE clause
  • New accessor methods across all frameworks:

    • ggvis(source) - Returns Altair Chart object
    • ggsql(source) - Returns ggsql specification string
    • ggtitle(source) - Returns visualization title
  • Tabbed UI: All framework app() methods now display Data / Filter Plot / Query Plot tabs

  • Auto re-rendering: Filter visualization automatically updates when filtered data changes (Shiny)

  • System prompt: ggsql syntax reference included when visualization tools are enabled

Implementation Details

Framework Accessor Pattern Chart Rendering
Shiny qc.ggvis() (reactive) Native Altair via output_widget
Streamlit qc.ggvis() (session state) st.altair_chart()
Gradio qc.ggvis(state) (state dict) gr.Plot()
Dash qc.ggvis(state) (state dict) html.Iframe with srcDoc

Files Changed (Key)

  • pkg-py/src/querychat/_ggsql.py - New ggsql helper module
  • pkg-py/src/querychat/tools.py - Visualization tools
  • pkg-py/src/querychat/prompts/tool-visualize-*.md - Tool documentation
  • pkg-py/src/querychat/prompts/prompt.md - System prompt with ggsql syntax
  • pkg-py/src/querychat/_querychat_base.py - Base class accessor methods
  • pkg-py/src/querychat/_querychat_core.py - State management with viz fields
  • pkg-py/src/querychat/_shiny*.py - Shiny implementation
  • pkg-py/src/querychat/_streamlit.py - Streamlit implementation
  • pkg-py/src/querychat/_gradio.py - Gradio implementation
  • pkg-py/src/querychat/_dash*.py - Dash implementation

Test Coverage

  • 257 tests pass (21 skipped for optional dependencies)
  • New test files:
    • test_ggsql.py - ggsql helper unit tests
    • test_viz_tools.py - Tool function tests
    • test_ggsql_integration.py - Integration tests

⚠️ Before Merging - Required Actions

1. ggsql Dependency

The ggsql package is currently referenced as a local path dependency:

"ggsql @ {root:uri}/../ggsql/ggsql-python"

Action needed: Update to PyPI reference once ggsql is published, or determine alternative distribution strategy.

2. Manual Testing

  • Test Shiny app with real LLM interactions
  • Test Streamlit app with real LLM interactions
  • Test Gradio app with real LLM interactions
  • Test Dash app with real LLM interactions
  • Verify visualizations render correctly in each framework

3. Documentation

  • Update user-facing documentation with visualization examples
  • Add ggsql syntax reference to docs site
  • Update changelog

4. Review Considerations

  • Confirm accessor method signatures are appropriate for each framework
  • Verify Dash Iframe approach is acceptable (vs native component)
  • Review system prompt ggsql syntax documentation for completeness

🤖 Generated with Claude Code

cpsievert and others added 3 commits January 27, 2026 15:49
Add core support for LLM-generated visualizations using ggsql syntax:

- Add ggsql and altair dependencies to pyproject.toml
- Create _ggsql.py with helpers for parsing and rendering visualizations
- Extend AppState with visualization state fields (filter_viz_*, query_viz_*)
- Implement visualize_dashboard and visualize_query tools in tools.py
- Add prompt templates for visualization tools with ggsql syntax reference
- Update system prompt with ggsql grammar documentation
- Add visualization accessor methods to QueryChatBase
- Export visualization data types (VisualizeDashboardData, VisualizeQueryData)

The ggsql DSL allows the LLM to generate chart specifications that are
rendered to Altair/Vega-Lite charts, supporting bar, line, point, area,
and boxplot marks with various encodings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Integrate ggsql visualization capabilities into all supported frameworks:

Shiny:
- Add visualization state to ServerValues dataclass
- Implement ggvis(), ggsql(), ggtitle() reactive accessors
- Add filter visualization re-rendering on data change
- Create tabbed UI with Data/Filter Plot/Query Plot tabs

Streamlit:
- Add ggvis(), ggsql(), ggtitle() methods reading from session state
- Create tabbed app layout with visualization tabs
- Render Altair charts with expandable ggsql specs

Gradio:
- Add ggvis(), ggsql(), ggtitle() methods taking state dict
- Create tabbed Blocks layout with visualization displays
- Wire state changes to update all visualization outputs

Dash:
- Add visualization callbacks and state management
- Create tabbed layout with dcc.Graph for Altair charts
- Add ggsql spec display in collapsible sections

All frameworks enable visualization tools by default and support
both filter (dashboard) and query visualizations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive test coverage for ggsql visualization features:

- test_ggsql.py: Unit tests for ggsql parsing and rendering
- test_ggsql_integration.py: Integration tests for end-to-end visualization
- test_viz_tools.py: Tests for visualize_dashboard and visualize_query tools
- test_visualization_tabs.py: Playwright tests for UI tab interactions
- Update test_state.py with visualization state field tests
- Update test_tools.py and test_base.py for new tool configurations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants