tidyverse / elmer

Call LLM APIs from R
http://elmer.tidyverse.org/
Other
196 stars 28 forks source link

Add method(s) for appending a `turn` to the chat #168

Open gadenbuie opened 2 days ago

gadenbuie commented 2 days ago

When using elmer with shinychat, users may have to construct both the message for shinychat::chat_append_message() and then separately call chat$stream() with the same message, or parts of it.

Here's an example app:

library(elmer)
library(shiny)
library(shinychat)

ui <- bslib::page_fluid(
  chat_ui("chat"),
  actionButton("ask_photo", "Ask question with image")
)

server <- function(input, output, session) {
  chat <- chat_openai(
    model = "gpt-4o",
  )

  observeEvent(input$ask_photo, {
    turn <- Turn(
      "user",
      list(
        ContentText("What photographic choices were made here, and why do you think the photographer chose them?"),
        content_image_file("photo.jpg")
      )
    )

    chat_append_message(
      "chat",
      list(
        role = "user",
        content = turn@text
      )
    )

    chat_append(
      "chat",
      chat$stream_async(!!!turn@contents)
    )
  })
}

shinyApp(ui, server)

It'd be helpful if there were a way to take the constructed turn and pass it directly to a chat method. Ideally even multiple turns at once to support advanced use cases.

hadley commented 1 day ago

I wonder if there's some way to make something like this work:

server <- function(input, output, session) {
  chat <- chat_openai(model = "gpt-4o")

  observeEvent(input$ask_photo, {
    stream <- chat$stream_async(
      ContentText("What photographic choices were made here, and why do you think the photographer chose them?"),
      content_image_file(system.file("httr2.png", package = "elmer"))
    )

    chat_append_message("chat", chat$last_turn("user"))
    chat_append_message("chat", stream)
  })
}

Currently that doesn't work because the user turn is only set after the stream is completed.