Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* To enable bookmarking in Express mode, set `shiny.express.app_opts(bookmark_store=)` during the app's initial construction.
* To enable bookmarking in Core mode, set `shiny.App(bookmark_store=)` when constructing the `app` object.

* Added a new `.enable_bookmarking(client)` method to `ui.Chat()`. This method will attach bookmark hooks to save and restore the chat's messages and client state. (#1951)
* Added a new `.enable_bookmarking(client)` method to `ui.Chat()`. This method will attach bookmark hooks to save and restore the chat's messages and client state. (#1951, #1954)

* Both `ui.Chat()` and `ui.MarkdownStream()` now support the inclusion of Shiny UI elements inside of messages. This allows for gathering input from the user (e.g., `ui.input_select()`), displaying of rich output (e.g., `render.DataGrid()`), and more. (#1868)

Expand Down
25 changes: 21 additions & 4 deletions shiny/ui/_chat_bookmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ def get_chatlas_state(
async def get_state() -> Jsonifiable:

turns: list[Turn[Any]] = client.get_turns()
return [turn.model_dump(mode="json") for turn in turns]
return {
"version": 1,
"turns": [turn.model_dump(mode="json") for turn in turns],
}

return get_state

Expand All @@ -84,12 +87,26 @@ def set_chatlas_state(

assert isinstance(client, Chat)

# TODO-future: Use pydantic model for validation
# instead of manual validation
async def set_state(value: Jsonifiable) -> None:

if not isinstance(value, list):
raise ValueError("Chatlas bookmark value was not a list of objects")
if not isinstance(value, dict):
raise ValueError("Chatlas bookmark value was not a dictionary")

turns: list[Turn[Any]] = [Turn.model_validate(turn_obj) for turn_obj in value]
version = value.get("version")
if version != 1:
raise ValueError(f"Unsupported Chatlas bookmark version: {version}")
turns_arr = value.get("turns")

if not isinstance(turns_arr, list):
raise ValueError(
"Chatlas bookmark value was not a list of chat message information"
)

turns: list[Turn[Any]] = [
Turn.model_validate(turn_obj) for turn_obj in turns_arr
]
client.set_turns(turns) # pyright: ignore[reportUnknownMemberType]

return set_state
Loading