% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/chat.R
\name{chat_append_message}
\alias{chat_append_message}
\title{Low-level function to append a message to a chat control}
\usage{
chat_append_message(
  id,
  msg,
  chunk = TRUE,
  operation = c("append", "replace"),
  icon = NULL,
  session = getDefaultReactiveDomain()
)
}
\arguments{
\item{id}{The ID of the chat element}

\item{msg}{The message to append. Should be a named list with \code{role} and
\code{content} fields. The \code{role} field should be either "user" or "assistant".
The \code{content} field should be a string containing the message content, in
Markdown format.}

\item{chunk}{Whether \code{msg} is just a chunk of a message, and if so, what
type. If \code{FALSE}, then \code{msg} is a complete message. If \code{"start"}, then
\code{msg} is the first chunk of a multi-chunk message. If \code{"end"}, then \code{msg}
is the last chunk of a multi-chunk message. If \code{TRUE}, then \code{msg} is an
intermediate chunk of a multi-chunk message. Default is \code{FALSE}.}

\item{operation}{The operation to perform on the message. If \code{"append"},
then the new content is appended to the existing message content. If
\code{"replace"}, then the existing message content is replaced by the new
content. Ignored if \code{chunk} is \code{FALSE}.}

\item{icon}{An optional icon to display next to the message, currently only
used for assistant messages. The icon can be any HTML element (e.g.,
\code{\link[htmltools:img]{htmltools::img()}} tag) or a string of HTML.}

\item{session}{The Shiny session object}
}
\value{
Returns nothing (\code{invisible(NULL)}).
}
\description{
For advanced users who want to control the message chunking behavior. Most
users should use \code{\link[=chat_append]{chat_append()}} instead.
}
\examples{
\dontshow{if (interactive()) withAutoprint(\{ # examplesIf}
library(shiny)
library(coro)
library(bslib)
library(shinychat)

# Dumbest chatbot in the world: ignores user input and chooses
# a random, vague response.
fake_chatbot <- async_generator(function(id, 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**"
  )

  # Use low-level chat_append_message() to temporarily set a progress message
  chat_append_message(id, list(role = "assistant", content = "_Thinking..._ "))
  await(async_sleep(1))
  # Clear the progress message
  chat_append_message(id, list(role = "assistant", content = ""), operation = "replace")

  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("chat", input$chat_user_input)
    chat_append("chat", response)
  })
}

shinyApp(ui, server)
\dontshow{\}) # examplesIf}
}
