From 78d0cb3043b79bb6123a642117de5308aa3c1aba Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 1 May 2026 16:27:36 -0500 Subject: [PATCH 1/3] chore(pkg-py): require latest released versions of ggsql, shiny, shinychat Replace git direct references with PyPI releases now that all three packages have published the versions we need (ggsql 0.3.1, shiny 1.6.1, shinychat 0.3.1). Also removes the now-unnecessary `allow-direct-references` hatch metadata setting. --- pyproject.toml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 309a2c59..ce8e2027 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,8 +21,8 @@ maintainers = [ ] dependencies = [ "duckdb", - "shiny @ git+https://github.com/posit-dev/py-shiny.git", - "shinychat @ git+https://github.com/posit-dev/shinychat.git", + "shiny>=1.6.1", + "shinychat>=0.3.1", "htmltools", "chatlas>=0.13.2", "narwhals>=2.2.0", @@ -50,8 +50,7 @@ gradio = ["gradio>=6.0"] dash = ["dash-ag-grid>=31.0", "dash[async]>=3.1", "dash-bootstrap-components>=2.0", "pandas"] # Visualization with ggsql viz = [ - # Temporary direct reference until ggsql 0.3.0 is available on the package index. - "ggsql @ git+https://github.com/posit-dev/ggsql-python.git@refs/pull/5/head", + "ggsql>=0.3.1", "altair>=6.0", "shinywidgets>=0.8.0", "vl-convert-python>=1.9.0", @@ -72,9 +71,6 @@ required-environments = [ "sys_platform == 'darwin'", ] -[tool.hatch.metadata] -allow-direct-references = true - [tool.hatch.build.targets.wheel] packages = ["pkg-py/src/querychat"] include = ["py.typed"] @@ -101,8 +97,7 @@ dev = [ "polars>=1.0.0", "pyarrow>=14.0.0", "ibis-framework[duckdb]>=9.0.0", - # Temporary direct reference until ggsql 0.3.0 is available on the package index. - "ggsql @ git+https://github.com/posit-dev/ggsql-python.git@refs/pull/5/head", + "ggsql>=0.3.1", "altair>=6.0", "shinywidgets>=0.8.0", "vl-convert-python>=1.9.0", From 13f4a307dd1eb94deb170b5b551d60307f7b354d Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 1 May 2026 16:29:27 -0500 Subject: [PATCH 2/3] chore(pkg-py): reorder changelog entries --- pkg-py/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg-py/CHANGELOG.md b/pkg-py/CHANGELOG.md index ff0e3f08..d373812e 100644 --- a/pkg-py/CHANGELOG.md +++ b/pkg-py/CHANGELOG.md @@ -11,11 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added a `"visualize"` tool that lets the LLM create inline Altair charts from natural language requests using [ggsql](https://github.com/posit-dev/ggsql) — a SQL extension for declarative data visualization. Include it via `tools=("query", "visualize")` (or alongside `"update"`). Charts render inline in the chat with fullscreen support, a "Show Query" toggle, and Save as PNG/SVG. Install the optional dependencies with `pip install querychat[viz]`. (#219) -* The `querychat_query` tool now accepts an optional `collapsed` parameter. When `collapsed=True`, the result card starts collapsed so preparatory or exploratory queries don't clutter the conversation. The LLM is guided to use this automatically when running queries before a visualization. +* `QueryChat()` now supports deferred chat client initialization. Pass `client=` to `server()` to provide a session-scoped chat client, enabling use cases where API credentials are only available at session time (e.g., Posit Connect managed OAuth tokens). When no `client` is specified anywhere, querychat resolves a sensible default from the `QUERYCHAT_CLIENT` environment variable (or `"openai"`). (#205) * Added support for Snowflake Semantic Views. When connected to Snowflake (via SQLAlchemy or Ibis), querychat automatically discovers available Semantic Views and includes their definitions in the system prompt. This helps the LLM generate correct queries using the `SEMANTIC_VIEW()` table function with certified business metrics and dimensions. (#200) -* `QueryChat()` now supports deferred chat client initialization. Pass `client=` to `server()` to provide a session-scoped chat client, enabling use cases where API credentials are only available at session time (e.g., Posit Connect managed OAuth tokens). When no `client` is specified anywhere, querychat resolves a sensible default from the `QUERYCHAT_CLIENT` environment variable (or `"openai"`). (#205) +* The `querychat_query` tool now accepts an optional `collapsed` parameter. When `collapsed=True`, the result card starts collapsed so preparatory or exploratory queries don't clutter the conversation. The LLM is guided to use this automatically when running queries before a visualization. ### Improvements From b486641019955dbeb0666ac88721135fe9b2f6e7 Mon Sep 17 00:00:00 2001 From: Carson Date: Fri, 1 May 2026 16:35:53 -0500 Subject: [PATCH 3/3] fix(pkg-py): stabilize flaky show-query toggle e2e test Wait for the first click's DOM update before issuing the second click, preventing a race where both clicks land before the toggle takes effect. --- pkg-py/tests/playwright/test_11_viz_footer.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg-py/tests/playwright/test_11_viz_footer.py b/pkg-py/tests/playwright/test_11_viz_footer.py index 46c887fa..39be35c5 100644 --- a/pkg-py/tests/playwright/test_11_viz_footer.py +++ b/pkg-py/tests/playwright/test_11_viz_footer.py @@ -98,15 +98,17 @@ def test_chevron_rotates_on_expand(self, page: Page) -> None: def test_toggle_hides_section_again(self, page: Page) -> None: """Clicking the button a second time should hide the query section.""" btn = page.locator(".querychat-show-query-btn") - btn.click() # show - btn.click() # hide + label = btn.locator(".querychat-query-label") - section = page.locator(".querychat-query-section") - expect(section).not_to_have_class("querychat-query-section--visible") + btn.click() # show + expect(label).to_have_text("Hide Query") - label = btn.locator(".querychat-query-label") + btn.click() # hide expect(label).to_have_text("Show Query") + section = page.locator(".querychat-query-section--visible") + expect(section).not_to_be_attached() + def test_query_section_contains_code(self, page: Page) -> None: """The revealed query section should contain the ggsql code.""" btn = page.locator(".querychat-show-query-btn")