Skip to content
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

Add support for custom printing of chat responses for knitr/Quarto #220

Open
cwickham opened this issue Dec 13, 2024 · 2 comments
Open

Add support for custom printing of chat responses for knitr/Quarto #220

cwickham opened this issue Dec 13, 2024 · 2 comments

Comments

@cwickham
Copy link

It would be really nice if there was a way to leverage the markdown output from LLM responses in Quarto documents.

For example, a code chunk in a Quarto document like:

```{r}
library(elmer)

chat <- chat_claude(
  system_prompt = "You are a friendly but terse assistant. You always use markdown syntax for code.",
)
chat$chat("How can I access the first element of a vector in R?")
```

Might end up rendering to something like:

Image

Using #| output: asis gets you part-way there but it really needs some styling to set it apart from the other body text in the document. There's not an easy way to do this from the Quarto side.

CC @cderv

@cderv
Copy link

cderv commented Dec 16, 2024

Current way of doing that with knitr logic is

---
title: "."
keep-md: true
---

```{r}
#| message: false
library(elmer)

chat <- chat_github(
  system_prompt = "You are a friendly but terse assistant. You always use markdown syntax for code.",
)
chat$chat("How can I access the first element of a vector in R?") |> knitr:::pandoc_div("callout-note") |> knitr::asis_output()
```

This is what a custom knit_print could do if the chat() output had a class it could be applied on.

@cderv
Copy link

cderv commented Dec 16, 2024

@cwickham in the meantime this is also possible to create a knitr custom engine, and format output of the engine as you would like

---
title: "elmer engine"
keep-md: true
---

```{r}
#| echo: false
knitr::knit_engines$set(
  elmer = function(options) {
    if (isFALSE(options$eval)) {
      return(knitr::engine_output(options, options$code, ""))
    }
    elmer_chatt <- options$chat
    if (is.character(elmer_chatt)) {
      elmer_chatt = get(elmer_chatt, envir = knitr::knit_global())
    }
    if (is.null(elmer_chatt)) {
      stop("A chat_* object is required to use 'elmer' engine. See https://elmer.tidyverse.org/", call. = FALSE)
    }
    res <- elmer_chatt$chat(options$code)
    # quarto context
    if (!is.null(knitr::opts_knit$get('quarto.version'))) {
      xfun::fenced_div(
        attrs = ".callout-note",
        c(
          "## Reply from chat using `elmer`",
          "", 
          res
        )
      ) |> paste0(collapse = "\n") |> knitr::asis_output()
    } else {
      xfun::fenced_div(
        attrs = '.elmer-output',
        res
      ) |> paste0(collapse = "\n") |> knitr::asis_output()
    }
  }
)
```


```{r}
#| message: false
library(elmer)

chat <- chat_github(
  system_prompt = "You are a friendly but terse assistant. You always use markdown syntax for code.",
)
```

```{elmer}
#| chat: chat
"How can I access the first element of a vector in R?"
```

Leads to
Image

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

No branches or pull requests

2 participants