Skip to content

feat(pkg-py): add ggsql visualization tool#201

Merged
cpsievert merged 35 commits intomainfrom
feat/ggsql-integration
Apr 28, 2026
Merged

feat(pkg-py): add ggsql visualization tool#201
cpsievert merged 35 commits intomainfrom
feat/ggsql-integration

Conversation

@cpsievert
Copy link
Copy Markdown
Contributor

@cpsievert cpsievert commented Jan 21, 2026

Summary

Adds an opt-in visualize tool to querychat's Python package, enabling LLM-generated data visualizations via ggsql. When enabled, the LLM can write ggsql queries (SQL + VISUALISE clause) that are executed and rendered as interactive Altair charts inline in the chat.

Usage

Install

pip install querychat[viz]

This installs the optional dependencies: ggsql, altair, shinywidgets, and vl-convert-python.

Example app

from querychat import QueryChat
from querychat.data import titanic

qc = QueryChat(
    titanic(),
    "titanic",
    tools=("query", "visualize"),
)

app = qc.app()

The visualize tool is opt-in — include it in the tools tuple alongside "query" and/or "update" to enable it.

What it looks like

Charts render inline in the chat with a collapsible footer showing the ggsql query (with syntax highlighting), a copy button, and save options:

Screenshot 2026-03-20 at 7 04 42 PM

Key changes

  • visualize tool (opt-in via tools=("query", "visualize")): The LLM writes a full ggsql query, which is executed against the data source and rendered as an Altair chart.
  • Two-stage ggsql pipeline (_viz_ggsql.py): Uses DataSource for SQL execution (preserving database pushdown), then feeds results into ggsql for VISUALISE processing → Altair chart.
  • Inline chart rendering (_viz_altair_widget.py): Custom AltairWidget for rendering charts directly in the chat stream, with JS/CSS assets for interactive display.
  • Prompt restructuring: System and tool prompts were reorganized into a unified structure. The LLM is guided to favor visualization over redundant table output, and preparatory queries are collapsed. A comprehensive ggsql syntax reference is included for the LLM.
  • Viz state is internal only: No public accessor methods or reactive values for viz state — it's managed entirely by the module/app internals.
    • This is somewhat intentional for now given that there will likely be a "second pass" at ggsql support. At that point, Maybe it will become more clear what sort of state accessor methods might be useful beyond "give me the latest chart".
  • Documentation: Added a visualization guide (docs/visualize.qmd) with examples and screenshots.

Comment thread pyproject.toml Outdated
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from a21712c to 05687d5 Compare March 3, 2026 20:34
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from 05687d5 to 8f33d70 Compare March 3, 2026 20:38
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from 8f33d70 to a3bdcbd Compare March 3, 2026 20:40
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from a3bdcbd to 3e15610 Compare March 3, 2026 20:52
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from 3e15610 to ac299be Compare March 4, 2026 00:04
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from 1450755 to a711326 Compare March 4, 2026 01:10
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from a711326 to 8696fca Compare March 4, 2026 01:15
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from 8696fca to db264dd Compare March 4, 2026 01:16
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from db264dd to 5a7e9de Compare March 4, 2026 01:19
cpsievert and others added 8 commits April 17, 2026 22:26
Updates syntax guide for ggsql v0.2.4 breaking changes: rect→tile,
linear merged into rule, array syntax to parentheses, updated text
aesthetics. Fixes pre-existing errors (invalid position fill, nonexistent
density stacking). Bumps ggsql dependency to >=0.2.4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Addresses PR feedback that "visualize_query" sounds like it might
provide a visual representation of a query rather than visualizing data.

Renames across source, prompts, docs, examples, and tests:
- Tool name: querychat_visualize_query → querychat_visualize
- Functions: tool_visualize_query → tool_visualize
- Types: VisualizeQueryData → VisualizeData, VisualizeQueryResult → VisualizeResult
- Template var: has_tool_visualize_query → has_tool_visualize
- Prompt file: tool-visualize-query.md → tool-visualize.md
- User-facing string: "visualize_query" → "visualize"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
LLM was generating trailing commas in LABEL clauses causing parse errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restores the title + description + usage guidance convention in
tool-query.md and tool-update-dashboard.md, keeping new additions
like the collapsed parameter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cpsievert cpsievert force-pushed the feat/ggsql-integration branch from de20a94 to 231e3ef Compare April 20, 2026 16:38
cpsievert and others added 3 commits April 20, 2026 11:48
Adds title/description/when-to-use/constraints to tool-visualize.md
following the same convention as the other tool prompts. Removes
duplicated routing and error recovery guidance from the system prompt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests now check for "Avoid redundant expanded results" instead of
removed headings/content that moved to tool-visualize.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds null mapping, rect/errorbar geoms, subtitle/caption labels,
lollipop/ridgeline examples, scale oob setting, and facet panel
filtering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

This comment was marked as resolved.

cpsievert and others added 4 commits April 20, 2026 12:13
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Divide height by row count for facet and concat specs (previously
  each cell got the full usable height, causing vertical overflow)
- Handle row/column grid facets by counting distinct values per
  facet field from the DataFrame
- Infer wrapping facet row count from data when columns is set
- Import IntoFrameT from narwhals directly instead of re-export via _datasource
- Import GREETING_PROMPT from _querychat_core where it's defined and exported
- Add type: ignore[arg-type] for DataFrame.__getitem__ returning Series | DataFrame
- Add pyright: ignore[reportPrivateImportUsage] for dash dcc components
@cpsievert cpsievert merged commit 5b50121 into main Apr 28, 2026
7 checks passed
@cpsievert cpsievert deleted the feat/ggsql-integration branch April 28, 2026 21:39
cpsievert added a commit that referenced this pull request Apr 28, 2026
Port of the Python ggsql visualization feature (#201) to the R package.

Adds an opt-in `visualize` tool that enables LLM-generated data
visualizations via ggsql. When enabled, the LLM writes ggsql queries
(SQL + VISUALISE clause) that are executed and rendered as interactive
charts inline in the chat using ggsql's native Shiny bindings.
cpsievert added a commit that referenced this pull request Apr 30, 2026
Port of the Python ggsql visualization feature (#201) to the R package.

Adds an opt-in `visualize` tool that enables LLM-generated data
visualizations via ggsql. When enabled, the LLM writes ggsql queries
(SQL + VISUALISE clause) that are executed and rendered as interactive
charts inline in the chat using ggsql's native Shiny bindings.
cpsievert added a commit that referenced this pull request Apr 30, 2026
Port of the Python ggsql visualization feature (#201) to the R package.

Adds an opt-in `visualize` tool that enables LLM-generated data
visualizations via ggsql. When enabled, the LLM writes ggsql queries
(SQL + VISUALISE clause) that are executed and rendered as interactive
charts inline in the chat using ggsql's native Shiny bindings.
cpsievert added a commit that referenced this pull request May 4, 2026
Add a new Visualizations vignette, a Data visualization section to the
Tools vignette, a navbar entry in pkgdown, and a mention in the README,
mirroring the documentation added for the Python package in PR #201.
cpsievert added a commit that referenced this pull request May 4, 2026
Add a new Visualizations vignette, a Data visualization section to the
Tools vignette, a navbar entry in pkgdown, and a mention in the README,
mirroring the documentation added for the Python package in PR #201.
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.

3 participants