You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I’m using Python Shiny’s built-in ui.chat_ui() and chat.append_message() to build a chat interface. I’d like to insert a Shiny input (for example, an action link or a button) directly into a new chat message so that the user can interact with it. However, when I embed an input_action_link in the text passed to chat.append_message(...), Shiny displays the link visually but does not treat it as a real input (i.e., input.my_special_link() never increments).
The rationale for this approach is linked to best practices when building AI agents with a human in the loop. A chat-based input (which could even be constructed by an LLM) is a popular approach. It can be observed in ChatGPT, when user is asked to provide feedback. It can be found in the assistant-ui library (labeled "Generative UI"), where it is used to confirm an AI action, such transaction (https://blog.langchain.dev/assistant-ui/). Of course, one could just add such an element outside the chat, but it makes the GUI more complex and can be cumbersome when you have multiple tools and/or actions. Aligning all temporary one-off inputs with their chat context seems more proper.
Below is my minimal reproducible example. When you run it and enter a message in the chat, it appends a new chat message containing a “special link,” but that link isn’t recognized by Shiny. Uncommenting the workaround (inserting an empty <script> or using ui.insert_ui) does force a re-scan, making it work. But I’d like to avoid that if possible.
fromshinyimportApp, ui, reactiveapp_ui=ui.page_fluid(
ui.chat_ui("chat")
)
defserver(input, output, session):
# Initialize the chatchat=ui.Chat("chat")
@chat.on_user_submitasyncdefon_user_submit():
user_messages=chat.messages()
user_text=user_messages[-1]["content"]
shiny_link_html=ui.input_action_link("my_special_link", "Click me!")
# This appears as a link visually but doesn't increment input.my_special_link()awaitchat.append_message(
f"Here is a special link in the chat: {shiny_link_html}"
)
# Uncommenting the code below triggers a re-scan, which "fixes" it:# ui.insert_ui(# ui.HTML("<script></script>"),# selector="body",# where="beforeEnd"# )@reactive.effectdefwatch_special_click():
clicks=input.my_special_link()
ifclicks>0:
print(f"[Server] Special link clicked {clicks} time(s).")
app=App(app_ui, server)
Is there an official or recommended way to add Shiny inputs inside a chat message so that they’re automatically recognized by input[...] without needing a manual DOM insertion workaround?
Is there a stable, built-in function to trigger a “DOM re-bind” (like Shiny.bindAll() in R Shiny) from Python, rather than using ui.insert_ui(ui.HTML("<script></script>")) as a hack?
Is embedding Shiny inputs in chat messages expected to work in the future, or should I rely on separate UI insertion?
The text was updated successfully, but these errors were encountered:
2. Is there a stable, built-in function to trigger a “DOM re-bind” (like Shiny.bindAll() in R Shiny) from Python, rather than using ui.insert_ui(ui.HTML("<script></script>")) as a hack?
Shiny.bindAll() is part of the common client-side library used for both Shiny for Python and for R, so you can use it in this case.
@cpsievert will be able to give more context on the road map and his vision for embedding Shiny inputs in chat messages when he returns from vacation later this month. In the mean time, here's a small amount of JavaScript that you can use to bind Shiny inputs after they are added to the chat:
Throw that line in a ui.tags.script() in your UI and you're good to go. (I should warn, I'm not recommending this as The Way to Do It. We'll very likely do this automatically for users in the future.)
@cpsievert While here I noticed that we use a shiny-chat-append-message custom event to add messages to the chat; it might be useful if shiny chat also emitted a shiny-chat-appended-message event, maybe in #finalizeMessage, that could serve as a follow-up hook for custom interactions.
I’m using Python Shiny’s built-in
ui.chat_ui()
andchat.append_message()
to build a chat interface. I’d like to insert a Shiny input (for example, an action link or a button) directly into a new chat message so that the user can interact with it. However, when I embed aninput_action_link
in the text passed tochat.append_message(...)
, Shiny displays the link visually but does not treat it as a real input (i.e.,input.my_special_link()
never increments).The rationale for this approach is linked to best practices when building AI agents with a human in the loop. A chat-based input (which could even be constructed by an LLM) is a popular approach. It can be observed in ChatGPT, when user is asked to provide feedback. It can be found in the
assistant-ui
library (labeled "Generative UI"), where it is used to confirm an AI action, such transaction (https://blog.langchain.dev/assistant-ui/). Of course, one could just add such an element outside the chat, but it makes the GUI more complex and can be cumbersome when you have multiple tools and/or actions. Aligning all temporary one-off inputs with their chat context seems more proper.Below is my minimal reproducible example. When you run it and enter a message in the chat, it appends a new chat message containing a “special link,” but that link isn’t recognized by Shiny. Uncommenting the workaround (inserting an empty
<script>
or usingui.insert_ui
) does force a re-scan, making it work. But I’d like to avoid that if possible.Is there an official or recommended way to add Shiny inputs inside a chat message so that they’re automatically recognized by
input[...]
without needing a manual DOM insertion workaround?Is there a stable, built-in function to trigger a “DOM re-bind” (like
Shiny.bindAll()
in R Shiny) from Python, rather than usingui.insert_ui(ui.HTML("<script></script>"))
as a hack?Is embedding Shiny inputs in chat messages expected to work in the future, or should I rely on separate UI insertion?
The text was updated successfully, but these errors were encountered: