diff --git a/DESCRIPTION b/DESCRIPTION index dccbd84..91dc0a7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -20,5 +20,8 @@ Imports: tibble, stringr, jsonlite, - rlang -Remotes: r-lib/httr2 + rlang, + slap +Remotes: + r-lib/httr2, + tadascience/slap diff --git a/NAMESPACE b/NAMESPACE index 6286a94..6aa45f4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,6 +2,7 @@ S3method(as.data.frame,chat_response) S3method(as_messages,character) +S3method(as_messages,default) S3method(as_messages,list) S3method(as_msg,character) S3method(as_tibble,chat_response) @@ -14,6 +15,7 @@ export(stream) import(cli) import(httr2) import(rlang) +import(slap) import(stringr) import(tibble) importFrom(jsonlite,fromJSON) diff --git a/R/chat.R b/R/chat.R index b14f96b..a42d32a 100644 --- a/R/chat.R +++ b/R/chat.R @@ -18,10 +18,23 @@ chat <- function(messages, model = "mistral-tiny", ..., error_call = current_env()) { check_dots_empty(call = error_call) + messages <- as_messages(messages) %!% "Can't convert {.arg messages} to a list of messages." + req <- req_chat(messages, model = model, error_call = error_call) resp <- authenticate(req, error_call = error_call) |> req_mistral_perform(error_call = error_call) + + req_messages <- x$request$body$data$messages + df_req <- map_dfr(req_messages, as.data.frame) + + df_resp <- as.data.frame( + resp_body_json(x)$choices[[1]]$message[c("role", "content")] + ) + + rbind(df_req, df_resp) + + class(resp) <- c("chat", class(resp)) resp } @@ -36,8 +49,6 @@ req_chat <- function(messages, model = "mistral-tiny", stream = FALSE, ..., erro check_dots_empty(call = error_call) check_scalar_string(model, error_call = error_call) - messages <- as_messages(messages) - request(mistral_base_url) |> req_url_path_append("v1", "chat", "completions") |> authenticate(error_call = error_call) |> diff --git a/R/messages.R b/R/messages.R index bbe485d..f5b2fd2 100644 --- a/R/messages.R +++ b/R/messages.R @@ -1,7 +1,7 @@ #' Convert object into a messages list #' #' @param messages object to convert to messages -#' @param ... ignored +#' @inheritParams rlang::args_dots_empty #' @inheritParams rlang::args_error_context #' #' @examples @@ -10,10 +10,18 @@ #' as_messages(list(assistant = "hello", user = "hello")) #' #' @export -as_messages <- function(messages, ..., error_call = current_env()) { +as_messages <- function(messages, ...) { UseMethod("as_messages") } +#' @export +as_messages.default <- function(messages, ..., error_call = current_env()) { + cli_abort(c( + "No known method for objects of class {.cls {class(messages)}}.", + i = "Use as_messages() or as_messages()." + ), call = error_call) +} + #' @export as_messages.character <- function(messages, ..., error_call = current_env()) { check_dots_empty(call = error_call) @@ -57,12 +65,12 @@ check_role <- function(name = "", error_call = caller_env()) { name } -check_scalar_string <- function(x, error_call = caller_env(), arg_name = deparse(substitute(x))) { +check_scalar_string <- function(x, error_call = caller_env(), error_arg = caller_arg(x)) { if (!is.character(x)) { - cli_abort("{.arg {arg_name}} must be a single string, not {.obj_type_friendly {x}}. ", call = error_call) + cli_abort("{.arg {error_arg}} must be a single string, not {.obj_type_friendly {x}}. ", call = error_call) } if (length(x) != 1L) { - cli_abort("{.arg {arg_name}} must be a single string, not length {.code {length(x)}}. ", call = error_call) + cli_abort("{.arg {error_arg}} must be a single string, not length {.code {length(x)}}. ", call = error_call) } } diff --git a/R/zzz.R b/R/zzz.R index 0b62d03..9fd4446 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -3,6 +3,7 @@ #' @import httr2 #' @import tibble #' @import stringr +#' @import slap #' @importFrom purrr map_dfr map_chr pluck map2 list_flatten #' @importFrom jsonlite fromJSON NULL diff --git a/man/as_messages.Rd b/man/as_messages.Rd index 7d01a9e..5af8f19 100644 --- a/man/as_messages.Rd +++ b/man/as_messages.Rd @@ -4,17 +4,12 @@ \alias{as_messages} \title{Convert object into a messages list} \usage{ -as_messages(messages, ..., error_call = current_env()) +as_messages(messages, ...) } \arguments{ \item{messages}{object to convert to messages} -\item{...}{ignored} - -\item{error_call}{The execution environment of a currently -running function, e.g. \code{caller_env()}. The function will be -mentioned in error messages as the source of the error. See the -\code{call} argument of \code{\link[rlang:abort]{abort()}} for more information.} +\item{...}{These dots are for future extensions and must be empty.} } \description{ Convert object into a messages list