diff --git a/DESCRIPTION b/DESCRIPTION index 76cb199..dccbd84 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -4,7 +4,7 @@ Version: 0.0.0.9000 Authors@R: c( person("Romain", "François", email = "romain@tada.science", role = c("aut", "cre")), person("Felix", "Mil", email = "felix.mil.dev@gmail.com", role = "aut"), - person("James", "Wade", email = "github@jameshwade.com", role="aut") + person("James", "Wade", email = "github@jameshwade.com", role = "aut") ) Description: Interact with the 'Mistral.AI' api. License: MIT + file LICENSE @@ -21,3 +21,4 @@ Imports: stringr, jsonlite, rlang +Remotes: r-lib/httr2 diff --git a/NAMESPACE b/NAMESPACE index c964e37..4b6c332 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -12,3 +12,4 @@ import(tibble) importFrom(jsonlite,fromJSON) importFrom(purrr,map_chr) importFrom(purrr,map_dfr) +importFrom(purrr,pluck) diff --git a/R/chat.R b/R/chat.R index d6aaa92..1e9ade6 100644 --- a/R/chat.R +++ b/R/chat.R @@ -1,3 +1,24 @@ +#' Chat with the Mistral api +#' +#' @param text some text +#' @param model which model to use. See [models()] for more information about which models are available +#' @param ... ignored +#' @inheritParams httr2::req_perform +#' +#' @return Result text from Mistral +#' +#' @examples +#' \dontrun{ +#' chat("Top 5 R packages") +#' } +#' +#' @export +chat <- function(text = "What are the top 5 R packages ?", model = "mistral-tiny", ..., error_call = current_env()) { + req_chat(text, model, error_call = error_call) |> + req_mistral_perform(error_call = error_call) |> + resp_chat(error_call = error_call) +} + req_chat <- function(text = "What are the top 5 R packages ?", model = "mistral-tiny", stream = FALSE, error_call = caller_env()) { check_model(model, error_call = error_call) request(mistral_base_url) |> @@ -38,24 +59,3 @@ print.chat_tibble <- function(x, ...) { } invisible(x) } - -#' Chat with the Mistral api -#' -#' @param text some text -#' @param model which model to use. See [models()] for more information about which models are available -#' @param ... ignored -#' @inheritParams httr2::req_perform -#' -#' @return Result text from Mistral -#' -#' @examples -#' \dontrun{ -#' chat("Top 5 R packages") -#' } -#' -#' @export -chat <- function(text = "What are the top 5 R packages ?", model = "mistral-tiny", ..., error_call = current_env()) { - req <- req_chat(text, model, error_call = error_call) - resp <- req_perform(req, error_call = error_call) - resp_chat(resp, error_call = error_call) -} diff --git a/R/httr2.R b/R/httr2.R new file mode 100644 index 0000000..e56dd7e --- /dev/null +++ b/R/httr2.R @@ -0,0 +1,26 @@ +req_mistral_perform <- function(req, error_call = caller_env()) { + + url <- req$url + handle_req_perform_error <- function(err) { + bullets <- c(x = "with endpoint {.url {url}}") + + if (!inherits(err, "error_mistral_req_perform")) { + bullets <- c( + bullets, + i = "Make sure your api key is valid {.url https://console.mistral.ai/api-keys/}", + i = "And set the {.envvar MISTRAL_API_KEY} environment variable", + i = "Perhaps using {.fn usethis::edit_r_environ}" + ) + } + + cli::cli_abort( + bullets, class = c("error_mistral_req_perform"), + call = error_call, parent = err + ) + } + + withCallingHandlers( + req_perform(req), + error = handle_req_perform_error + ) +} diff --git a/R/models.R b/R/models.R index 1c31275..43e52f8 100644 --- a/R/models.R +++ b/R/models.R @@ -1,16 +1,3 @@ -check_model <- function(model, error_call = caller_env()) { - available_models <- models(error_call = error_call) - - if (!(model %in% available_models)) { - cli_abort(call = error_call, c( - "The model {model} is not available.", - "i" = "Please use the {.code models()} function to see the available models." - )) - } - - invisible(model) -} - #' Retrieve all models available in the Mistral API #' #' @inheritParams httr2::req_perform @@ -23,7 +10,7 @@ check_model <- function(model, error_call = caller_env()) { #' } #' #' @export -models <- function(error_call = caller_env()) { +models <- function(error_call = current_env()) { req <- request(mistral_base_url) |> req_url_path_append("v1", "models") |> @@ -32,9 +19,20 @@ models <- function(error_call = caller_env()) { use_on_error = TRUE, max_age = 2 * 60 * 60) # 2 hours - resp <- req_perform(req) |> - resp_body_json(simplifyVector = TRUE) + req_mistral_perform(req, error_call = error_call) |> + resp_body_json(simplifyVector = TRUE) |> + pluck("data","id") +} + +check_model <- function(model, error_call = caller_env()) { + available_models <- models(error_call = error_call) + + if (!(model %in% available_models)) { + cli_abort(call = error_call, c( + "The model {model} is not available.", + "i" = "Please use the {.code models()} function to see the available models." + )) + } - resp |> - purrr::pluck("data","id") + invisible(model) } diff --git a/R/stream.R b/R/stream.R index 2d49719..0524af2 100644 --- a/R/stream.R +++ b/R/stream.R @@ -15,7 +15,6 @@ stream <- function(text, model = "mistral-tiny", ..., error_call = current_env() invisible(resp) } -#' @importFrom purrr map_chr #' @importFrom jsonlite fromJSON stream_callback <- function(x) { txt <- rawToChar(x) diff --git a/R/zzz.R b/R/zzz.R index df14ed7..66e67f9 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -3,7 +3,7 @@ #' @import httr2 #' @import tibble #' @import stringr -#' @importFrom purrr map_dfr +#' @importFrom purrr map_dfr map_chr pluck NULL mistral_base_url <- "https://api.mistral.ai" diff --git a/man/models.Rd b/man/models.Rd index 19d5e51..0caeefb 100644 --- a/man/models.Rd +++ b/man/models.Rd @@ -4,7 +4,7 @@ \alias{models} \title{Retrieve all models available in the Mistral API} \usage{ -models(error_call = caller_env()) +models(error_call = current_env()) } \arguments{ \item{error_call}{The execution environment of a currently