diff --git a/pkg-r/DESCRIPTION b/pkg-r/DESCRIPTION index 66db21c3..61791642 100644 --- a/pkg-r/DESCRIPTION +++ b/pkg-r/DESCRIPTION @@ -30,7 +30,7 @@ Imports: jsonlite, lifecycle, promises (>= 1.3.2), - rlang, + rlang (>= 1.1.0), S7, shiny (>= 1.10.0) Suggests: diff --git a/pkg-r/NEWS.md b/pkg-r/NEWS.md index 7490bd4c..2f07280b 100644 --- a/pkg-r/NEWS.md +++ b/pkg-r/NEWS.md @@ -10,6 +10,8 @@ * Added `chat_append(icon=...)` and `chat_ui(icon_assistant=...)` for customizing the icon that appears next to assistant responses. (#88) +* `chat_mod_server()` now returns a list of reactives for `last_input` and `last_turn`, as well and functions to `update_user_input()` and `clear()` the chat. (#130) + ## Improvements * `chat_app()` now correctly restores the chat client state when refreshing the app, e.g. by reloading the page. (#71) diff --git a/pkg-r/R/chat_app.R b/pkg-r/R/chat_app.R index f7a60cff..14222572 100644 --- a/pkg-r/R/chat_app.R +++ b/pkg-r/R/chat_app.R @@ -74,7 +74,17 @@ #' * `chat_app()` returns a [shiny::shinyApp()] object. #' * `chat_mod_ui()` returns the UI for a shinychat module. #' * `chat_mod_server()` includes the shinychat module server logic, and -#' and returns the last turn upon successful chat completion. +#' and a list with: +#' +#' * `last_input`: A reactive value containing the last user input. +#' * `last_turn`: A reactive value containing the last assistant turn. +#' * `update_user_input()`: A function to update the chat input or submit a +#' new user input. Takes the same arguments as [update_chat_user_input()], +#' except for `id` and `session`, which are supplied automatically. +#' * `clear()`: A function to clear the chat history and the chat UI. +#' Takes a single argument, `clear_history`, which indicates whether to +#' also clear the chat history in the `client` object. Defaults to `TRUE`. +#' * `client`: The chat client object, which is mutated as you chat. #' #' @describeIn chat_app A simple Shiny app for live chatting. Note that this #' app is suitable for interactive use by a single user; do not use @@ -173,7 +183,11 @@ chat_mod_server <- function( bookmark_on_response = bookmark_on_response ) + last_turn <- shiny::reactiveVal(NULL) + last_input <- shiny::reactiveVal(NULL) + shiny::observeEvent(input$chat_user_input, { + last_input(input$chat_user_input) append_stream_task$invoke( client, "chat", @@ -181,10 +195,46 @@ chat_mod_server <- function( ) }) - shiny::reactive({ + shiny::observe({ if (append_stream_task$status() == "success") { - client$last_turn() + last_turn(client$last_turn()) } }) + + list( + last_turn = shiny::reactive(last_turn()), + last_input = shiny::reactive(last_input()), + client = client, + update_user_input = function( + value = NULL, + ..., + placeholder = NULL, + submit = FALSE, + focus = FALSE + ) { + update_chat_user_input( + "chat", + value = value, + placeholder = placeholder, + submit = submit, + focus = focus, + ..., + session = session + ) + }, + clear = function(clear_history = TRUE) { + if (!rlang::is_bool(clear_history)) { + cli::cli_abort( + "{.var clear_history} must be {.or {.val {c(TRUE, FALSE)}}}." + ) + } + chat_clear("chat", session = session) + if (isTRUE(clear_history)) { + client$set_turns(list()) + } + last_turn(NULL) + last_input(NULL) + } + ) }) } diff --git a/pkg-r/man/chat_app.Rd b/pkg-r/man/chat_app.Rd index f1646cc5..b61066da 100644 --- a/pkg-r/man/chat_app.Rd +++ b/pkg-r/man/chat_app.Rd @@ -48,7 +48,18 @@ in \code{\link[=chat_ui]{chat_ui()}}.} \item \code{chat_app()} returns a \code{\link[shiny:shinyApp]{shiny::shinyApp()}} object. \item \code{chat_mod_ui()} returns the UI for a shinychat module. \item \code{chat_mod_server()} includes the shinychat module server logic, and -and returns the last turn upon successful chat completion. +and a list with: +\itemize{ +\item \code{last_input}: A reactive value containing the last user input. +\item \code{last_turn}: A reactive value containing the last assistant turn. +\item \code{update_user_input()}: A function to update the chat input or submit a +new user input. Takes the same arguments as \code{\link[=update_chat_user_input]{update_chat_user_input()}}, +except for \code{id} and \code{session}, which are supplied automatically. +\item \code{clear()}: A function to clear the chat history and the chat UI. +Takes a single argument, \code{clear_history}, which indicates whether to +also clear the chat history in the \code{client} object. Defaults to \code{TRUE}. +\item \code{client}: The chat client object, which is mutated as you chat. +} } } \description{