Repository navigation
Conversation
This was referenced Oct 12, 2026
cpsievert
force-pushed
the
ggsql-caching-reader
branch
from
October 13, 2026 15:10
9b765ba to
65d885f
Compare
cpsievert
force-pushed
the
feat/maps-capability-py
branch
from
October 13, 2026 15:10
de7d660 to
d0fa8b3
Compare
cpsievert
force-pushed
the
ggsql-caching-reader
branch
5 times, most recently
from
October 13, 2026 18:14
54a3b1f to
2ddfa98
Compare
cpsievert
force-pushed
the
feat/maps-capability-py
branch
from
October 13, 2026 19:42
d0fa8b3 to
0639c98
Compare
Pass tools=("default", "maps") to let the LLM draw choropleths (via the
builtin ggsql:world dataset) and point maps through ggsql's spatial
support:
- New ggsql-spatial prompt partial, rendered into the system prompt when
maps are enabled.
- The "default" tools entry expands to the default tool set, so extra
capabilities no longer require restating every tool.
- The DuckDB spatial extension is pre-warmed when the viz reader is
first created with maps enabled; if setup fails, the session
continues without maps.
- Spatial-extension errors are translated into actionable guidance for
the LLM (do not retry with DRAW spatial / ggsql:world; suggest a
non-map visualization instead) when maps are disabled or setup
failed.
cpsievert
force-pushed
the
feat/maps-capability-py
branch
from
October 13, 2026 19:44
0639c98 to
6dca9b2
Compare
prewarm_spatial routed INSTALL/LOAD spatial through execute(), which targets the user's primary data source. Those connections are typically locked down (filesystem access disabled), so the install failed and the "maps" capability was silently disabled — and even where it succeeded it would take no effect on the connection that matters. Spatial SQL actually executes on the CachingReader's private in-memory cache connection (the compute surface), so install/load the extension there via the new ggsql.CachingReader.execute_sql_cached binding (posit-dev/ggsql-python#14) and keep the smoke query on execute(), where it exercises the full spatial path: extension load, builtin ggsql:world registration, spatial layer execution. Without a ggsql build that has execute_sql_cached, prewarm fails with a warning and maps stay unavailable, so this degrades gracefully.
… app The LLM kept putting lon/lat/size in global VISUALISE mappings, which every layer inherits — and the spatial background layer only accepts geometry/fill/stroke/opacity, so the query failed with "Layer 'spatial' does not support the `lat`, `size`, `lon` mappings". The prompt now states explicitly that point aesthetics belong on DRAW point MAPPING. Also adds examples/13-maps-app.py: a Shiny Express demo with two live datasets (USGS real-time earthquakes, World Bank GDP) exercising the point map, choropleth, and orthographic globe patterns. Note: the globe suggestion currently triggers a suspected OOM in ggsql's orthographic projection of ggsql:world (under investigation); it is kept here as a repro.
cpsievert
added a commit
to posit-dev/ggsql-python
that referenced
this pull request
Oct 14, 2026
* feat: add execute_sql_cached binding to CachingReader Exposes the Rust CachingReader's compute surface (execute_sql_cached, present since ggsql 0.5.2) to Python. Setup statements that ggsql's derived SQL depends on must run on the private cache connection where that SQL executes — e.g. INSTALL/LOAD of DuckDB extensions such as spatial. Routing them through execute_sql sends them to the primary instead, where locked-down connections reject them and they take no effect on the cache. This is needed by querychat's opt-in "maps" capability to prewarm the DuckDB spatial extension on the compute surface (posit-dev/querychat#323). * docs: changelog entry for CachingReader.execute_sql_cached * docs: reorder changelog entries
ggsql's bundled DuckDB starts extension-free, while the DuckDB CLI and Python client load ICU by default — so SQL that works everywhere else (e.g. `TIMESTAMPTZ - INTERVAL`, the standard way to write temporal filters) failed on the viz engine with a binder error. Seen in the wild: an LLM-generated earthquake map query failed repeatedly on `-(TIMESTAMP WITH TIME ZONE, INTERVAL)` before recovering. prewarm_spatial (now prewarm_compute_surface, since it is no longer spatial-only) also installs/loads ICU on the CachingReader's cache connection, alongside spatial. Cost: a one-time ~15 MB download per machine per DuckDB version, then ~60 ms per startup. Unlike spatial, ICU failure is non-fatal (maps don't need it): warn and continue.
A previous commit on this branch made viz_dep() use a dep_version() helper whose definition was never committed, so importing querychat._viz_tools raised ImportError and the Python CI job on #323 failed at collection time. Restore the direct __version__ usage.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in
"maps"capability to querychat for Python, letting the LLM draw choropleths and point maps through ggsql's spatial support (spec in localdocs/superpowers/specs/2026-10-12-maps-capability-design.md).Stacked on #321 — the
ggsql:worldjoin pattern requires full-query execution throughggsql.CachingReader. The diff againstggsql-caching-readeradditionally shows a fewmaincommits because #321's branch is behindmain; it will clean up when #321 merges and this retargets.How it works:
tools=("default", "maps")."default"is a new sentinel that expands to the default tool set (also fixes the existing "must restate every tool to add one" problem);"maps"is a capability modifier that validation requires alongside"visualize".icuextension (all sessions — DuckDB's CLI/Python client load it by default, so LLM-written SQL assumes it) and, for maps-enabled clients, thespatialextension (INSTALL/LOADvia ggsql setup statements, plus a smoke query). Spatial failure (e.g. no network for the one-time download) warns and marks maps unavailable for the session; ICU failure warns and continues.ggsql-spatial.mdpartial is included in the system prompt only when maps is enabled. It teaches theggsql:worldchoropleth-join pattern (verified to execute ggsql-side, so it works against any backend), lon/lat point maps, named projections, and guardrails (noINSTALL/LOADfrom the LLM;ST_*functions are allowed only on the ggsql compute connection, not in data queries).visualizeis on butmapsis not, the system prompt tells the LLM that maps exist, forbids spatial syntax, and gives it thetools=("default", "maps")enablement message plus a lon/lat-scatter fallback.st_*catalog) error is translated into actionable "setup failed, suggest a non-map chart instead" guidance instead of a raw error.Known limitation: bookmark-restored viz widgets use a separate reader that is not pre-warmed, so restored spatial charts may fail on restore (they skip with the existing restore warning). Wiring maps into the restore path can follow later.
Verification
ggsql:worldschema, cross-source join staging, extension auto-load behavior).