Skip to contents

shinychat 0.4.0

CRAN release: 2026-06-01

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_cancel parameter to chat_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, and chat_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 the title attribute 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 via chat_ui(greeting=) or dynamically from the server with chat_set_greeting(). They are automatically dismissed when the user sends their first message. A new greeting_requested input 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(), or content_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 footer parameter to chat_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-size and --shiny-chat-footer-color CSS custom properties. (#224)

  • Tool result cards now support a fullscreen toggle. Set full_screen = TRUE in the display list (or set res$full_screen <- NA in a custom contents_shinychat() method) to add a button that expands the card to fill the viewport. Press Escape, click the backdrop, or use the close button to exit fullscreen.

  • Added footer field to ToolResultDisplay for displaying custom HTML content below the tool result card body. (#178)

  • chat_mod_server() now returns a set_client(new_client, sync = TRUE) function for swapping the chat client used by the module at runtime. When sync = 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 a status reactive 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 via set_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)

shinychat 0.3.0

CRAN release: 2025-11-20

Breaking changes

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 using chat_append() with chat_ui(), set stream = "content" when you call the $stream_async() method on the ellmer::Chat client to ensure tool calls are included in the chat stream output. Learn more in the tool calling UI article. (#52)

  • Added chat_append(icon=...) and chat_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 a data-role attribute 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 any shiny-user-message rules to use shiny-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)

shinychat 0.2.0

CRAN release: 2025-05-16

New features and improvements

Bug fixes

shinychat 0.1.1

CRAN release: 2024-12-18

  • Initial CRAN submission.