ui.chat_ui
ui.chat_ui(
id,
*,
messages=None,
greeting=None,
placeholder='Enter a message...',
width='min(clamp(680px, 50vw, 760px), 100%)',
height='auto',
fill=True,
icon_assistant=None,
icon_send=None,
enable_cancel=MISSING,
submit_key='enter',
allow_attachments=MISSING,
toolbar_input=None,
footer=None,
tool_grouping='tool',
drawer=True,
show_history=True,
**kwargs,
)UI container for a chat component (Shiny Core).
This function is for locating a Chat instance in a Shiny Core app. If you are using Shiny Express, use the ui method instead.
Parameters
id :-
A unique identifier for the chat UI.
messages :-
Deprecated. Non-empty startup messages can’t be recorded by the conversation-history feature. Use
greetingfor a startup message, use.append_message()to replay messages from the server, or sethistory=Falseon the server-sideChatif you’re managing conversation state yourself. A sequence of messages to display in the chat. A given message can be one of the following: * A string, which is interpreted as markdown and rendered to HTML on the client. * To prevent interpreting as markdown, mark the string asHTML. * A UI element (specifically, aTagChild). * This includesTagList, which takes UI elements (including strings) as children. TagList content is treated as HTML: strings inside it are literal text (HTML-escaped), not markdown. UseHTMLfor trusted raw HTML strings. * A dictionary withcontentandrolekeys. Thecontentkey can contain a content as described above, and therolekey can be “assistant” or “user”. * Advanced: to interleave markdown and UI in one message, construct aChatMessagewithparts=[...]— an ordered list of bare strings (markdown segments) and structured block dicts. This segment API is provisional and may change in a future release. * More generally, any type registered withshinychat.message_content. NOTE: content may include specially formatted input suggestion links (seeappend_messagefor more info). greeting :-
An optional greeting to display at the top of the chat before any conversation messages. Can be a markdown string or a
chat_greetingobject. For a dynamic or streaming greeting, useset_greetingfrom the server instead. When no greeting is set and the chat is visible with no messages, an input named{id}_greeting_requestedfires. Use this input with@reactive.event(input.{id}_greeting_requested)to generate a greeting on demand from the server. It fires again afterclear_messagesis called withgreeting=True. placeholder :-
Placeholder text for the chat input.
width :-
The width of the chat container.
height :-
The height of the chat container.
fill :-
Whether the chat should vertically take available space inside a fillable container.
icon_assistant :-
The icon to use for the assistant chat messages. Can be a HTML or a tag in the form of
HTMLorTag.None(the default) orFalseomits the assistant icon entirely. PassTrueto use the built-in robot icon (individual messages can still opt in to a different icon via theiconargument of.append_message()). icon_send :-
The icon to use for the chat input’s ready-state submit button. Can be a HTML or a tag in the form of
HTMLorTag. IfNone(the default) orFalse, a default arrow icon is used. The button provides a filled circular surface (state-colored background, white icon); the supplied icon replaces only the glyph inside it. The button’s appearance is controlled by CSS variables set on the chat container or any ancestor: *--shiny-chat-btn-send-size– button width and height (default24px) *--shiny-chat-input-icon-size– icon size, shared with the attach button (default22px) *--shiny-chat-btn-send-bg– button background (default: state color) *--shiny-chat-btn-send-color– icon color (default:#fff) *--shiny-chat-btn-send-border– button border (default:none) *--shiny-chat-btn-send-color-ready– ready/pending state color (default:--bs-primary) *--shiny-chat-btn-send-color-empty– empty/disabled state color (default:--bs-gray-500) *--shiny-chat-btn-send-color-cancel– cancel/cancelling state color (default:--bs-danger) For example, a ghost (outline) style that fills on hover: .. code-block:: css :root .shiny-chat-btn-send { –shiny-chat-btn-send-bg: transparent; –shiny-chat-btn-send-color: var(–_btn-send-state-color); –shiny-chat-btn-send-border: 1px solid var(–_btn-send-state-color); –shiny-chat-btn-send-color-hover: #fff; –shiny-chat-btn-send-bg-hover: var(–_btn-send-state-color); } (--_btn-send-state-coloris an internal variable that resolves on the button itself, so ghost-style rules must target the button element rather than an ancestor.) enable_cancel :-
Whether to show a stop button during streaming that allows the user to cancel the in-progress response. When
True, the chat UI shows a stop button in place of the send button while streaming. You must observeinput.<id>_cancelon the server and callctrl.cancel()on a chatlasStreamControllerto actually stop the stream. When left unset (the default), a chat driven by aclient=enables the stop button automatically; otherwise it stays hidden. Passing an explicitTrue/Falsealways wins over that automatic behavior. submit_key :-
Controls which key combination submits the chat message: -
"enter"(default): Enter submits, Shift+Enter adds a newline. -"enter+modifier": Ctrl+Enter (Cmd+Enter on Mac) submits, plain Enter adds a newline. allow_attachments :-
Controls the file-attachment affordance (an attach button, plus clipboard paste and drag-and-drop) in the chat input. Pass
Trueto accept all supported types (PNG, JPEG, GIF, WebP, PDF, and common text/code files such as Markdown, plain text, CSV, JSON, and source files),Falseto disable, or a list of MIME types to restrict what is accepted (each must be one of the supported types). Attachments are delivered to your.on_user_submit()handler’s second argument as alist[Attachment], where each item exposesmime,name,size, anddata_urlattributes (and forwarded to aclient=automatically). When left unset (the default), a chat driven by aclient=enables attachments automatically; otherwise it stays hidden. The maximum combined size of all attachments in a single message is controlled globally by theSHINYCHAT_MAX_ATTACHMENT_SIZEenvironment variable (a raw byte count; defaults to approximately 30 MB). Files that would push the total over this cap are rejected in the browser with a notice. When bookmarking is enabled, preferbookmark_store="server": attachment data is saved in the bookmark and can exceed URL length limits withbookmark_store="url". toolbar_input :-
Optional HTML content displayed directly below the chat input. Use
shiny.ui.toolbarto group toolbar controls. footer :-
Optional HTML content displayed in a bottom-pinned, full-width chat region. This can be any HTML content (tags, tag lists, or strings). Useful for adding disclaimers, attribution, or other information. The footer text is styled slightly smaller and lighter than body text by default. Customize with CSS properties
--shiny-chat-footer-font-sizeand--shiny-chat-footer-coloron the chat container or footer element. tool_grouping :-
Controls how tool calls are grouped together in the UI: -
"tool"(default): calls to the same tool within a tool-calling loop are grouped into a single activity row. This groups by tool name across the whole loop, not just consecutive calls – e.g. calls to toolsX,Y,Z,X,Y(in that order) are grouped intoX(2 calls),Y(2 calls), andZ(1 call). -"all": every tool call within a tool-calling loop is grouped into a single activity row, regardless of tool name. -"none": each tool call is shown in its own activity row. Prose or thinking between calls starts a new tool-calling loop, so grouping never crosses those transcript boundaries. Individual tools can override this via agroupingtool annotation. For chatlas tools, preferannotations={"extra": {"grouping": ...}}: a top-levelgroupingkey is also read, but it isn’t part of chatlas’ToolAnnotations, so type checkers reject it. Chat-level"none"always disables grouping, even when a tool annotation requests"tool"or"all". drawer :-
Whether the artifact panel is available. Pass a
ChatDrawerto supply its initial content and configuration. show_history :-
Whether to render the chat’s built-in history selector.
kwargs :-
Additional attributes for the chat container element.
Examples
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 400
## file: app.py
from shiny import App, ui
app_ui = ui.page_fillable(
ui.panel_title("Hello Shiny Chat"),
ui.chat_ui(
"chat",
greeting="""
Hi! This is a simple Shiny `Chat` UI. Enter a message below and I will
simply repeat it back to you.
To learn more about chatbots and how to build them with Shiny, check out
[the documentation](https://shiny.posit.co/py/docs/genai-chatbots.html).
""",
),
fillable_mobile=True,
)
def server(input, output, session):
chat = ui.Chat(id="chat")
# Define a callback to run when the user submits a message
@chat.on_user_submit
async def handle_user_input(user_input: str):
# Append a response to the chat
await chat.append_message(f"You said: {user_input}")
app = App(app_ui, server)
## file: requirements.txt
shiny
## file: _template.json
{
"type": "app",
"id": "chat-hello",
"title": "Hello Shiny Chat",
"next_steps": [
"Run the app with `shiny run app.py`."
]
}