Skip to content

py/v0.6.1 - #319

Merged
gadenbuie merged 6 commits into
py-v0.6.1from
py-rc-v0.6.0
Aug 14, 2026
Merged

py/v0.6.1#319
gadenbuie merged 6 commits into
py-v0.6.1from
py-rc-v0.6.0

Conversation

@gadenbuie

@gadenbuie gadenbuie commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Backports #313, #297, #289, and #275 onto the Python v0.6.0 release.

Summary

This PR prepares the Python v0.6.1 maintenance release while intentionally excluding unrelated changes made on main since v0.6.0.

The original PRs were applied chronologically. Most Python changes applied cleanly, with these reconciliation choices:

Release process

Once this PR is approved, we intend to:

  1. Merge it into the py-v0.6.1 maintenance branch.
  2. Publish a GitHub Release targeting that merge commit with the tag py/v0.6.1.
  3. Let .github/workflows/py-release.yaml rerun the Python checks, build the wheel and source distribution, and publish them to PyPI through trusted publishing.

The fixes already exist on main, so this maintenance branch does not need to be merged back into main.

Verification

  • Ruff passed
  • Pyright passed
  • 342 non-browser Python tests passed
  • 2 targeted Playwright greeting/history tests passed
  • Wheel and sdist builds passed
  • twine check passed
  • An exact-version shinychat 0.6.1 wheel installed and imported successfully in a clean environment

gadenbuie and others added 6 commits August 14, 2026 14:40
)

* fix(py,r): reject unsupported conversation-history schema versions

FileConversationStore/InMemoryConversationStore now validate
schema_version on read (get/list) and write (put) against
MIN_SCHEMA_VERSION/MAX_SCHEMA_VERSION, rejecting unsupported versions
before decoding or before any filesystem mutation. HistoryController
routes all store.get()/list() calls through internal helpers that
validate records regardless of which ConversationStore implementation
is in use, so custom stores can't bypass the check.

Fixes #312

* test(py,r): cover schema-version rejection on read, write, and custom stores

Adds tests for unsupported schema_version on get()/list(), rejecting
writes into an empty store and over an existing unsupported record
(asserting files are left byte-for-byte unchanged), InMemoryConversationStore
input rejection, legacy missing-schema_version round-trip, and a custom
ConversationStore whose output HistoryController rejects before it
reaches client state.

Also fixes two bugs surfaced by the new R tests in
FileConversationStore: list()'s tryCatch handler re-signaled the
unsupported-schema condition via stop(e), which was still caught by
the sibling error handler in the same tryCatch call; and put()'s
on-disk preflight used file.exists() without excluding directories,
breaking the existing atomic-rename-failure test.

Fixes #312

* docs(py,r): add changelog entries for schema-version rejection fix

Fixes #312

* docs(py,r): reference PR in schema-version changelog entries

* fix(py,r): harden schema version validation

* docs(py,r): omit internal schema guard notes
* fix(py): serialize dictionary tool result displays

* fix(py): retain unknown tool display metadata

* test(py): cover persisted dictionary tool displays

* refactor(py): type chatlas turn serialization
* fix(pkg-py): degrade gracefully on a malformed bookmarked message

_restore_bookmark_message() raised on a malformed message dict (e.g. a
bookmark written by an incompatible shinychat version), which aborts
the caller's restore loop and silently drops every message after the
bad one too -- Shiny's generic on_restore error handling only shows a
banner, it doesn't resume the loop.

Python has no turns-derived fallback to route into the way R's
decode_ui_snapshot() does, so the proportionate fix here is
per-message: warn and skip just the bad message, restoring everything
else.

* docs(pkg-py): changelog for the malformed bookmarked message skip

* fix(pkg-py): don't leak message content into the malformed-bookmark warning

ValidationError's default string embeds the offending input value, which
for a chat segment is arbitrary (and possibly sensitive) message content.
Use errors(include_input=False) and format loc/msg ourselves instead.
* fix(pkg-py): defer greeting to history's restore decision

Resolving the app greeting used to race an independent client-side
`{id}_greeting_requested` request against the server's async history
restore: reloading into a restored conversation could flash the
greeting before the restore replaced it, and a restored conversation's
transcript had no way to suppress a stale/incoming greeting.

Greeting resolution now defers to the same "is this conversation
restored?" decision `HistoryController` already computes on init and
on `new_chat()`, instead of a separate client-driven signal. Restoring
a conversation (whether on initial load or via the history drawer)
now explicitly clears any greeting, since a restored conversation is
never a "new chat".

* fix(pkg-r): defer greeting to history's restore decision

Mirrors the pkg-py fix: resolving the app greeting used to race an
independent client-side `{id}_greeting_requested` request against the
server's async history restore, which could flash the greeting on a
restored conversation, or leave a fresh conversation with no greeting
at all if the session began by restoring one.

Greeting resolution now defers to the same "is this conversation
restored?" decision `HistoryController` already computes on init and
on `new_chat()`. Restoring a conversation now explicitly clears any
greeting, since a restored conversation is never a "new chat".

* fix(pkg-py): add missing set_greeting support to history test fakes

_ReplayFakeChat and _TrackingChat didn't implement set_greeting, which
replay_ui() now calls to suppress the app greeting on restore.

---------

Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
@gadenbuie gadenbuie changed the title Backport Python fixes for shinychat 0.6.1 py/v0.6.0 Aug 14, 2026
@gadenbuie gadenbuie changed the title py/v0.6.0 py/v0.6.1 Aug 14, 2026
@gadenbuie
gadenbuie requested a review from cpsievert August 14, 2026 19:10
@gadenbuie
gadenbuie marked this pull request as ready for review August 14, 2026 19:14

@cpsievert cpsievert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@gadenbuie
gadenbuie merged commit 37a3dfe into py-v0.6.1 Aug 14, 2026
9 of 10 checks passed
@gadenbuie
gadenbuie deleted the py-rc-v0.6.0 branch August 14, 2026 20:01
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