Releases: posit-dev/shinychat
[py] shinychat 0.5.1
[py] shinychat 0.5.0
New features
-
Chat()now accepts an optionalclient=parameter. When provided, streaming, cancellation, bookmarking, and greeting handling are wired up automatically — no manual plumbing required. Thechat.clientproperty exposes aChatClientwrapper with.value(the raw chatlas client),.set()for swapping models mid-session, and.clear()for resetting the conversation with flexible history management. -
Added slash commands: a typeahead command palette that lets users trigger named shortcuts directly from the chat input. Type
/to open the palette, filter by typing, and pick a command with arrow keys or click. Commands can expand into LLM prompts, trigger server-side side effects (clear chat, open a modal, export transcript), or be handled entirely client-side via the cancelableshiny:chat-slash-commandDOM event. Register commands withchat.slash_command(), which accepts 0- or 1-argument async handlers; 1-argument handlers receive the text typed after the command name asuser_input. Theechoparameter controls whether an invocation is recorded as a user message and triggers a loading state. Echoed commands are faithfully restored on bookmark/restore. (#239) -
Added
submit_keyparameter tochat_ui()andChat.ui():"enter"(default, Enter submits) or"enter+modifier"(Ctrl/Cmd+Enter submits, plain Enter inserts a line break). The input remains editable while a response is streaming — only submission is blocked, not typing. (#251)
Improvements
-
Bookmarking now correctly restores assistant messages that mix content types within a single message — for example a reply that combines markdown, a raw-HTML widget, and reasoning. Previously, restoring such a message could lose formatting or interactive components.
-
All navigating links in assistant messages now open in a new tab to preserve the app's session state. Cross-origin links still show the confirmation dialog; same-origin links open directly. (#238)
Breaking changes
- Removed the deprecated
formatandtoken_limitsparameters from.messages(), thetokenizerparameter fromChat(), and the.transform_user_input()decorator. These features overreached into LLM provider responsibilities; use your provider (e.g., chatlas, LangChain) to manage conversation formatting, token limits, and input transformation instead. Calling any of these now raises aTypeErrorwith migration guidance. (#245)
Bug fixes
-
Fixed the copy button on code blocks not working in some embedded contexts. (@thisisnic, #247)
-
Fixed the external link confirmation dialog not rendering in Safari. The backdrop overlay appeared but the dialog content was invisible due to a Bootstrap/
<dialog>CSS interaction. (#201, #238) -
Fixed pressing Escape to dismiss the external link dialog leaving it in a broken state where subsequent link clicks no longer worked. (#238)
-
Fixed a bug where
<thinking>tags inside fenced code blocks (```) or inline backtick spans were incorrectly treated as model reasoning content and hidden from the visible output. Also fixes a chunk-boundary false positive where a chunk ending with a non-newline character followed by a chunk beginning with<thinking>would enter thinking mode. (#235)
[r] shinychat 0.4.0
Experimental internal changes
- The chat UI's rendering layer has been migrated from Lit to React. This significantly improves streaming performance — incoming chunks no longer clear previous DOM state — and makes the codebase more maintainable. One trade-off is that certain Shiny UI elements embedded in chat messages may not work as well as before (e.g., inline
<script>tags are generally not supported inside a React runtime). If you encounter issues, please let us know.
New features and improvements
-
The chat UI now displays model reasoning/thinking content as collapsible panels above assistant responses. Thinking content streams in real-time with animated topic labels. This works with providers that support structured thinking (e.g., Claude's extended thinking via
ellmer) and with local models that wrap reasoning in<thinking>tags. (#208) -
Added
enable_cancelparameter tochat_ui()to show a stop button that lets users cancel an in-progress AI response. Press the stop button or hit Escape to cancel.chat_mod_ui()enables cancellation by default, andchat_mod_server()handles the cancellation wiring automatically, using the stream cancellation features introduced in ellmer v0.4.1. (#221) -
Markdown lists where every item is a
<span class="suggestion">are now rendered as a grid of clickable suggestion cards. Each suggestion's text content becomes both the card label and the value sent on click. To add a short heading above the body text, set thetitleattribute on the span — e.g.<span class="suggestion" title="Heading">Body text shown on the card.</span>. Only the body text (not the title) is submitted when the card is clicked. Cards stream in with staggered animations and support keyboard navigation (arrow keys, Home/End) with roving tabindex. (#219) -
Added
chat_greeting()for creating welcome messages that appear when the chat is empty. Greetings can be set statically viachat_ui(greeting=)or dynamically from the server withchat_set_greeting(). They are automatically dismissed when the user sends their first message. A newgreeting_requestedinput fires when the chat is visible, empty, and has no greeting, enabling LLM-generated welcome messages.chat_mod_server(greeting=)accepts a function for auto-generated greetings. (#217) -
Tool result cards now render images and PDFs returned by ellmer tools. When a tool returns
content_image_file(),content_image_url(), orcontent_pdf_file(), the result is displayed as an inline image or a PDF filename badge. Mixed content lists (e.g.,list(ContentText("summary"), content_image_file("plot.png"))) are rendered with items interleaved in order. (#225) -
Added
footerparameter tochat_ui()for displaying arbitrary HTML content below the chat input. Useful for disclaimers, attribution, or interactive toolbars. Styled with sensible defaults and customizable via--shiny-chat-footer-font-sizeand--shiny-chat-footer-colorCSS custom properties. (#224) -
Tool result cards now support a fullscreen toggle. Set
full_screen = TRUEin thedisplaylist (or setres$full_screen <- NAin a customcontents_shinychat()method) to add a button that expands the card to fill the viewport. PressEscape, click the backdrop, or use the close button to exit fullscreen. -
Added
footerfield toToolResultDisplayfor displaying custom HTML content below the tool result card body. (#178) -
chat_mod_server()now returns aset_client(new_client, sync = TRUE)function for swapping the chat client used by the module at runtime. Whensync = TRUE(the default), the new client inherits the current conversation's turns, system prompt, and tools so the conversation continues seamlessly. If a response is currently streaming, the swap is deferred until the stream completes. (#227) -
chat_mod_server()now returns astatusreactive that reports the current interaction state:"idle"when no response is in progress, or"streaming"while a response is actively being received. (#227) -
chat_restore()now invisibly returns a cancel function that tears down all bookmark registrations made by that call. This is useful when swapping the chat client viaset_client(), which handles the re-registration automatically. (#227)
Improvements
- All navigating links in assistant messages now open in a new tab to preserve the app's session state. Cross-origin links still show the confirmation dialog; same-origin links open directly. (#238)
Bug fixes
-
Fixed the external link confirmation dialog not rendering in Safari. The backdrop overlay appeared but the dialog content was invisible due to a Bootstrap/
<dialog>CSS interaction. (#201, #238) -
Fixed pressing Escape to dismiss the external link dialog leaving it in a broken state where subsequent link clicks no longer worked. (#238)
-
Fixed an issue where user chat messages would display the default assistant icon. (#162)
[py] shinychat 0.4.0
New features
-
The chat UI now displays model reasoning/thinking content as collapsible panels above assistant responses. Thinking content streams in real-time with animated topic labels. This works with providers that support structured thinking (e.g., Claude's extended thinking via
chatlas) and with local models that wrap reasoning in<thinking>tags. (#208) -
Added
chat_greeting()for creating welcome messages that appear when the chat is empty. Greetings can be set statically viachat_ui(greeting=)or dynamically withChat.set_greeting(), and are dismissed when the user sends their first message. A new{id}_greeting_requestedinput fires when the chat is visible, empty, and has no greeting, enabling LLM-generated welcome messages. (#217) -
Added
enable_cancelparameter tochat_ui()andChat.ui()to show a stop button that lets users cancel an in-progress AI response. Press the stop button or hit Escape to cancel. Wire up theinput.<id>_cancelevent to achatlas.StreamController(introduced in chatlas v0.18.0) to connect the UI to your chat provider. (#221) -
Added
footerparameter tochat_ui()andChat.ui()for displaying arbitrary HTML content below the chat input. Useful for disclaimers, attribution, or interactive toolbars. Styled with sensible defaults and customizable via--shiny-chat-footer-font-sizeand--shiny-chat-footer-colorCSS custom properties. (#224) -
The chat input now supports history navigation: press Up/Down arrow keys when the input is empty to cycle through previously sent messages. Editing a recalled message locks navigation until the input is cleared. (#222)
Improvements
-
Tool result cards now render images and PDFs returned by chatlas tools. When a tool returns
ContentImageInline,ContentImageRemote, orContentPDF, the result is displayed as an inline image or a PDF filename badge. Mixed content lists (e.g.,[ContentText("summary"), content_image_file("plot.png")]) are rendered with items interleaved in order. Standalone image and PDF content items in turn history are also rendered correctly. (#225) -
Markdown lists where every item is a
<span class="suggestion">are now rendered as a grid of clickable suggestion cards. Each suggestion's text content becomes both the card label and the value sent on click. To add a short heading above the body text, set thetitleattribute on the span — e.g.<span class="suggestion" title="Heading">Body text shown on the card.</span>. Only the body text (not the title) is submitted when the card is clicked. Cards stream in with staggered animations and support keyboard navigation (arrow keys, Home/End) with roving tabindex. (#219) -
Updated minimum
chatlasversion to>=0.15.0. (#208)
Bug fixes
[py] shinychat 0.3.2
Bug fixes
- Updated for compatibility with htmltools 0.7.0.
split_html_islandsnow recognizes the newTagifiedTag/TagifiedTagListsibling classes when deciding which children carry thedata-shinychat-reactattribute, andTool*Component.tagify()implementations are annotated withhtmltools.Tagifiedand return fully-tagified output per the new Tagifiable contract. (#226)
[py] shinychat 0.3.1
Bug fixes
- Fixed an issue where Shiny UI components (e.g., inputs) passed to
MarkdownStream'scontentparameter could fail to initialize, especially on WebKit-based browsers. (#205)
[py] shinychat 0.3.0
Experimental internal changes
- The chat UI's rendering layer has been migrated from Lit to React. This significantly improves streaming performance — incoming chunks no longer clear previous DOM state — and makes the codebase more maintainable. One trade-off is that certain Shiny UI elements embedded in chat messages may not work as well as before (e.g., inline
<script>tags are generally not supported inside a React runtime). If you encounter issues, please let us know.
New features
-
Tool result cards now support a fullscreen toggle. Set
full_screen=TrueinToolResultDisplay()to add a button that expands the card to fill the viewport. PressEscape, click the backdrop, or use the close button to exit fullscreen. (#179) -
Added
footerparameter toToolResultDisplayfor displaying custom HTML content below the tool result card body. (#178)
Breaking changes
-
Removed the deprecated
transform_userandtransform_assistantparameters from.messages(). As a result,.messages()now always returns transformed content (i.e., the result of applying.transform_user_input()/.transform_assistant_response(), if any), meaning it's better reflection of UI state than LLM-facing message state. This change reflects a greater change in philosophy thatshinychatshouldn't be managing LLM message state (a backend framework likechatlas,langchain,pydantic, etc. should do this instead). (#193) -
Removed the deprecated
transformparameter from.user_input()..user_input()now always returns the currently stored user message content, which matches the simplified transform handling used by.messages(). (#193) -
ChatMessageDict(returned by.messages()) may now include anhtml_depskey containing serializedHTMLDependencydicts. Code that unpacks or iterates these dicts with a fixed set of keys should be updated to handle the new field. (#193)
Improvements
-
Streaming messages now support mid-stream content type transitions. When the content type changes during streaming, previous content is preserved as a frozen segment, maintaining HTML islands and Shiny bindings. (#199)
-
Replaced the custom auto-scroll implementation with the
use-stick-to-bottomlibrary for smoother stick-to-bottom behavior during streaming. A centered "scroll to bottom" button now appears when the user scrolls away from the bottom. (#195) -
Migrated Google provider from the deprecated
google-generativeaiSDK togoogle-genai. (#174)
Bug fixes
-
Fixed chat message content touching the right edge of the container. (#197)
-
Fixed content inside tool cards (e.g., widgets, plots) not re-laying out when the card is collapsed or expanded. (#180)
-
Fixed the chat UI crashing on non-HTTPS contexts (e.g., RStudio Server over plain HTTP) due to
crypto.randomUUID()being unavailable outside secure contexts. (#186, #187) -
Fixed pyright 1.1.409 compatibility by adding missing
__all__exports. (#200)
[py] shinychat 0.2.9
r-shinychat 0.3.0
Breaking changes
chat_mod_server()now returns a list of reactives forlast_inputandlast_turn, as well functions toupdate_user_input(),append()andclear()the chat. (#130, #143, #145)
New features
-
Added
chat_restore()which adds Shiny bookmarking hooks to save and restore the{ellmer}chat client. (#28, #82) -
Added
update_chat_user_input()for programmatically updating the user input of a chat UI element. (#78) -
shinychat now shows tool call request and results in the UI, and the feature is enabled by default in
chat_app()and the chat module (chat_mod_server()). When usingchat_append()withchat_ui(), setstream = "content"when you call the$stream_async()method on theellmer::Chatclient to ensure tool calls are included in the chat stream output. Learn more in the tool calling UI article. (#52) -
Added
chat_append(icon=...)andchat_ui(icon_assistant=...)for customizing the icon that appears next to assistant responses. (#88)
Improvements
-
chat_app()now correctly restores the chat client state when refreshing the app, e.g. by reloading the page. (#71) -
External links in chat messages in
chat_ui()now open in a new tab by default, with a confirmation dialog. (#120)
Bug fixes
- The chat input no longer submits incomplete text when the user has activated IME completions (e.g. while typing in Japanese or Chinese). (#85)
Internal changes
-
We consolidated the
<shiny-chat-message>and<shiny-user-message>components into a single<shiny-chat-message>component with adata-roleattribute to indicate whether it's an "assistant" or "user" message. This likely has minimal impact on your apps, other than custom styles. You should update anyshiny-user-messagerules to useshiny-chat-message[data-role="user"]. (#101) -
The chat UI's send input button is now identified by the class
.shiny-chat-btn-send. (@DeepanshKhurana, #138)
py-shinychat 0.2.8
Bug fixes
- Allow
chatlas.types.ToolResultDisplayto be imported withoutpydantic.