Skip to content

Support Shiny UI inside of chat_append() and markdown_stream() #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 14, 2025

Conversation

cpsievert
Copy link
Collaborator

@cpsievert cpsievert commented Feb 25, 2025

This PR adds support for the content of a message provided to chat_append() or markdown_stream() to include Shiny UI, and moreover, if that UI includes output or input bindings, they are bound to the server session.

This means, among other things, you can now display things like {htmlwidgets} and collect user input from things like a select input. Here are a couple basic examples:

Output example
library(shiny)
library(shinychat)
library(bslib)
library(plotly)

welcome <- list(
  list(
    "**Hello! Here is a statically rendered widget**",
    plot_ly(x = 1, y = 1, mode = "text", text = "Statically rendered widget")
  ),
  list(
    "**And here is an output binding**",
    plotlyOutput("plt")
  )
)

ui <- page_fillable(
  title = "Hello widgets in chat",
  fillable_mobile = TRUE,
  chat_ui("chat", messages = welcome)
)

server <- function(input, output, session) {

  observeEvent(input$chat_user_input, {
    chat_append("chat", paste("You said:", input$chat_user_input))
  })

  output$plt <- renderPlotly({
    plot_ly(x = 1, y = 1, mode = "text", text = "Dynamically rendered widget")
  })

}


shinyApp(ui, server)
Input example
library(ellmer)
library(shiny)
library(shinychat)
library(bslib)
library(plotly)


welcome <- list(
  list(
    "**Hello! How would you like me to respond?**",
    selectInput("tone", "", choices = c("Happy", "Sad"))
  )
)

ui <- page_fillable(
  title = "Hello input bindings in chat",
  fillable_mobile = TRUE,
  chat_ui("chat", messages = welcome)
)

server <- function(input, output, session) {

  chat <- chat_ollama(model = "llama3.2")

  observeEvent(input$chat_user_input, {
    stream <- chat$stream_async(input$chat_user_input)
    chat_append("chat", stream)
  })

  observeEvent(input$tone, {
    chat$set_system_prompt(paste("You are a terse and", input$tone, "assistant."))
  })

}


shinyApp(ui, server)

TODO

@cpsievert cpsievert marked this pull request as ready for review March 12, 2025 22:48
@cpsievert cpsievert requested a review from gadenbuie March 12, 2025 22:49
Copy link
Collaborator

@gadenbuie gadenbuie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I just left a few very minor comments

@cpsievert cpsievert merged commit da73dff into main Mar 14, 2025
6 checks passed
@cpsievert cpsievert deleted the shiny-chat-bind branch March 14, 2025 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants