Skip to content

feat(pkg-r): add ggsql visualization tool#224

Draft
cpsievert wants to merge 2 commits intomainfrom
feat/ggsql-integration-r-v2
Draft

feat(pkg-r): add ggsql visualization tool#224
cpsievert wants to merge 2 commits intomainfrom
feat/ggsql-integration-r-v2

Conversation

@cpsievert
Copy link
Copy Markdown
Contributor

@cpsievert cpsievert commented Apr 28, 2026

Summary

R port of #201. Adds an opt-in visualize tool to querychat's R 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 charts inline in the chat.

Usage

Install

pak::pak("posit-dev/ggsql-r")

Example app

library(querychat)

qc <- QueryChat$new(
  palmerpenguins::penguins,
  tools = c("update", "query", "visualize")
)

qc$app()

The visualize tool is opt-in — include "visualize" in the tools vector 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 = c("query", "visualize")): The LLM writes a full ggsql query, which is executed against the data source and rendered using ggsql's native Shiny bindings (ggsql::renderGgsql / ggsql::ggsqlOutput).
  • Two-stage ggsql pipeline (querychat_viz.R): Uses DataSource for SQL execution (preserving database pushdown), then feeds results into ggsql's DuckDB reader for VISUALISE processing.
  • Inline chart rendering: Charts render directly in the chat stream via Shiny's dynamic output system, with JS/CSS assets for the footer (show query toggle, save as PNG/SVG).
  • Generated footer assets: pkg-r/inst/htmldep/viz.{js,css} are checked-in package assets, but the shared source/build logic for them already lives on main under js/ (see js/build.mjs). This PR is adding the R package's generated copies, not introducing a second implementation of that browser logic.
  • PNG feedback to LLM: A static PNG is generated (best-effort, requires V8 + rsvg) and sent back to the LLM so it can see what it produced.
  • collapsed parameter on querychat_query: Preparatory queries (e.g., inspecting data before visualizing) can start collapsed so the chart remains the focal point.
  • Prompt restructuring: System and tool prompts were updated to match the Python package — visualization best practices, ggsql syntax reference, and conditional sections based on which tools are enabled.
  • Bookmark support: Viz widget state is saved/restored during Shiny bookmarking.
  • Viz state is internal only: No public accessor methods or reactive values for viz state — consistent with the Python implementation.

Test plan

  • Unit tests for execute_ggsql, extract_visualise_table, has_layer_level_source
  • Unit tests for tool_visualize_dashboard (creation, callback, error handling)
  • Unit tests for truncate_error
  • Unit tests for collapsed parameter on query tool
  • Unit tests for viz prompt conditionals in system prompt
  • Full test suite passes (622 tests, 0 failures)

@cpsievert cpsievert force-pushed the feat/ggsql-integration-r-v2 branch from cd14057 to 5731d0a Compare April 28, 2026 22:54
Comment thread pkg-r/R/querychat_viz.R Outdated
@cpsievert cpsievert marked this pull request as draft April 29, 2026 14:14
Comment thread pkg-r/inst/prompts/ggsql-syntax.md Outdated
@cpsievert cpsievert force-pushed the feat/ggsql-integration-r-v2 branch from f52f440 to afbbfba Compare April 30, 2026 15:54
Comment thread pkg-r/R/QueryChat.R Outdated
Comment thread pkg-py/src/querychat/_viz_tools.py Outdated
Comment thread pkg-py/src/querychat/_viz_tools.py Outdated

This comment was marked as resolved.

@cpsievert cpsievert force-pushed the feat/ggsql-integration-r-v2 branch from 8a1928a to b79b71e Compare May 1, 2026 22:27
For TblSqlSource, execute_query() returns a lazy tbl_sql which
ggsql_register() can't handle. Materialize it first, matching the
existing pattern in app_obj().
@cpsievert cpsievert requested a review from gadenbuie May 1, 2026 22:38
@cpsievert
Copy link
Copy Markdown
Contributor Author

@gadenbuie ready for your eyes if you'd like to have a look. CI is failing since ggsql isn't yet on CRAN, but it should happen in the next few days. Will get CI is passing before merging.

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