Skip to contents

The chat_append function appends a message to an existing chat control. The response can be a string, string generator, string promise, or string promise generator (as returned by the elmer package's chat, stream, chat_async, and stream_async methods, respectively).

This function should be called from a Shiny app's server. It is generally used to append the model's response to the chat, while user messages are added to the chat UI automatically by the front-end. You'd only need to use chat_append(role="user") if you are programmatically generating queries from the server and sending them on behalf of the user, and want them to be reflected in the UI.

Usage

chat_append(
  id,
  response,
  role = c("assistant", "user"),
  session = getDefaultReactiveDomain()
)

Arguments

id

The ID of the chat element

response

The message or message stream to append to the chat element

role

The role of the message (either "assistant" or "user"). Defaults to "assistant".

session

The Shiny session object

Value

Returns a promise. This promise resolves when the message has been successfully sent to the client; note that it does not guarantee that the message was actually received or rendered by the client. The promise rejects if an error occurs while processing the response (see the "Error handling" section).

Error handling

If the response argument is a generator, promise, or promise generator, and an error occurs while producing the message (e.g. an elmer chat object errors during stream_async), the promise returned by chat_append will reject with the error. If the chat_append call is the last expression in a Shiny observer, Shiny will see that the observer failed, and end the user session. If you prefer to handle the error gracefully, use promises::catch() on the promise returned by chat_append.

Examples

if (FALSE) { # interactive()
library(shiny)
library(coro)
library(bslib)
library(shinychat)

# Dumbest chatbot in the world: ignores user input and chooses
# a random, vague response. For a chatbot, try {elmer}.
fake_chatbot <- async_generator(function(input) {
  responses <- c(
    "What does that suggest to you?",
    "I see.",
    "I'm not sure I understand you fully.",
    "What do you think?",
    "Can you elaborate on that?",
    "Interesting question! Let's examine thi... **See more**"
  )

  await(async_sleep(1))
  for (chunk in strsplit(sample(responses, 1), "")[[1]]) {
    yield(chunk)
    await(async_sleep(0.02))
  }
})

ui <- page_fillable(
  chat_ui("chat", fill = TRUE)
)

server <- function(input, output, session) {
  observeEvent(input$chat_user_input, {
    response <- fake_chatbot(input$chat_user_input)
    chat_append("chat", response)
  })
}

shinyApp(ui, server)
}