diff --git a/shiny/ui/_chat.py b/shiny/ui/_chat.py index b4024f4f3..5a0ded26d 100644 --- a/shiny/ui/_chat.py +++ b/shiny/ui/_chat.py @@ -1434,6 +1434,14 @@ def chat_ui( id = resolve_id(id) + icon_attr = None + if icon_assistant is not None: + icon_attr = str(icon_assistant) + + icon_deps = None + if isinstance(icon_assistant, (Tag, TagList)): + icon_deps = icon_assistant.get_dependencies() + message_tags: list[Tag] = [] if messages is None: messages = [] @@ -1462,13 +1470,10 @@ def chat_ui( tag_name, ui["dependencies"], content=ui["html"], + icon=icon_attr, ) ) - html_deps = None - if isinstance(icon_assistant, (Tag, TagList)): - html_deps = icon_assistant.get_dependencies() - res = Tag( "shiny-chat-container", Tag("shiny-chat-messages", *message_tags), @@ -1478,7 +1483,7 @@ def chat_ui( placeholder=placeholder, ), chat_deps(), - html_deps, + icon_deps, { "style": css( width=as_css_unit(width), @@ -1488,7 +1493,9 @@ def chat_ui( id=id, placeholder=placeholder, fill=fill, - icon_assistant=str(icon_assistant) if icon_assistant is not None else None, + # Also include icon on the parent so that when messages are dynamically added, + # we know the default icon has changed + icon_assistant=icon_attr, **kwargs, ) diff --git a/tests/playwright/shiny/components/chat/icon/app.py b/tests/playwright/shiny/components/chat/icon/app.py index 035b8a539..4908fff2d 100644 --- a/tests/playwright/shiny/components/chat/icon/app.py +++ b/tests/playwright/shiny/components/chat/icon/app.py @@ -31,19 +31,14 @@ async def handle_user_input_default(user_input: str): await chat_default.append_message(f"You said: {user_input}") # Animal Bot ---------------------------------------------------------------------- - chat_animal = ui.Chat( - id="chat_animal", - messages=[ - { - "content": "Hello! I'm Animal Bot. How can I help you today?", - "role": "assistant", - }, - ], - ) + chat_animal = ui.Chat(id="chat_animal") with ui.div(): ui.h2("Animal Bot") - chat_animal.ui(icon_assistant=faicons.icon_svg("otter").add_class("icon-otter")) + chat_animal.ui( + messages=["Hello! I'm Animal Bot. How can I help you today?"], + icon_assistant=faicons.icon_svg("otter").add_class("icon-otter"), + ) ui.input_select("animal", "Animal", choices=["Otter", "Hippo", "Frog", "Dove"]) @chat_animal.on_user_submit @@ -68,42 +63,30 @@ async def handle_user_input_otter(user_input: str): """ - chat_svg = ui.Chat( - id="chat_svg", - messages=[ - { - "content": "Hello! I'm SVG Bot. How can I help you today?", - "role": "assistant", - }, - ], - ) + chat_svg = ui.Chat(id="chat_svg") with ui.div(): ui.h2("SVG Bot") - chat_svg.ui(icon_assistant=ui.HTML(bs_icon_info_circle_fill)) + chat_svg.ui( + messages=["Hello! I'm SVG Bot. How can I help you today?"], + icon_assistant=ui.HTML(bs_icon_info_circle_fill), + ) @chat_svg.on_user_submit async def handle_user_input_svg(user_input: str): await chat_svg.append_message(f"You said: {user_input}") # Image Bot ----------------------------------------------------------------------- - chat_image = ui.Chat( - id="chat_image", - messages=[ - { - "content": "Hello! I'm Image Bot. How can I help you today?", - "role": "assistant", - }, - ], - ) + chat_image = ui.Chat(id="chat_image") with ui.div(): ui.h2("Image Bot") chat_image.ui( + messages=["Hello! I'm Image Bot. How can I help you today?"], icon_assistant=ui.img( src="img/grace-hopper.jpg", class_="icon-image grace-hopper", - ) + ), ) ui.input_select("image", "Image", choices=["Grace Hopper", "Shiny"])