% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/llm_provider.R
\name{llm_provider-class}
\alias{llm_provider-class}
\title{LlmProvider R6 Class}
\description{
This class provides a structure for creating \linkS4class{llm_provider}
objects with different implementations of \verb{$complete_chat()}.
Using this class, you can create an \linkS4class{llm_provider} object that interacts
with different LLM providers, such Ollama, OpenAI, or other custom providers.
}
\examples{
# Example creation of a llm_provider-class object:
llm_provider_openai <- function(
    parameters = list(
      model = "gpt-4o-mini",
      stream = getOption("tidyprompt.stream", TRUE)
    ),
    verbose = getOption("tidyprompt.verbose", TRUE),
    url = "https://api.openai.com/v1/chat/completions",
    api_key = Sys.getenv("OPENAI_API_KEY")
) {
  complete_chat <- function(chat_history) {
    headers <- c(
      "Content-Type" = "application/json",
      "Authorization" = paste("Bearer", self$api_key)
    )

    body <- list(
      messages = lapply(seq_len(nrow(chat_history)), function(i) {
        list(role = chat_history$role[i], content = chat_history$content[i])
      })
    )

    for (name in names(self$parameters))
      body[[name]] <- self$parameters[[name]]

    request <- httr2::request(self$url) |>
      httr2::req_body_json(body) |>
      httr2::req_headers(!!!headers)

    request_llm_provider(
      chat_history,
      request,
      stream = self$parameters$stream,
      verbose = self$verbose,
      api_type = self$api_type
    )
  }

  return(`llm_provider-class`$new(
    complete_chat_function = complete_chat,
    parameters = parameters,
    verbose = verbose,
    url = url,
    api_key = api_key,
    api_type = "openai"
  ))
}

llm_provider <- llm_provider_openai()

\dontrun{
  llm_provider$complete_chat("Hi!")
  # --- Sending request to LLM provider (gpt-4o-mini): ---
  # Hi!
  # --- Receiving response from LLM provider: ---
  # Hello! How can I assist you today?
}
}
\seealso{
Other llm_provider: 
\code{\link{llm_provider_ellmer}()},
\code{\link{llm_provider_google_gemini}()},
\code{\link{llm_provider_groq}()},
\code{\link{llm_provider_mistral}()},
\code{\link{llm_provider_ollama}()},
\code{\link{llm_provider_openai}()},
\code{\link{llm_provider_openrouter}()},
\code{\link{llm_provider_xai}()}
}
\concept{llm_provider}
\section{Public fields}{
\if{html}{\out{<div class="r6-fields">}}
\describe{
\item{\code{parameters}}{A named list of parameters to configure the \linkS4class{llm_provider}.
Parameters may be appended to the request body when interacting with the
LLM provider API}

\item{\code{verbose}}{A logical indicating whether interaction with the LLM provider should be
printed to the console}

\item{\code{url}}{The URL to the LLM provider API endpoint for chat completion}

\item{\code{api_key}}{The API key to use for authentication with the LLM provider API}

\item{\code{api_type}}{The type of API to use (e.g., "openai", "ollama", "ellmer").
This is used to determine certain specific behaviors for different APIs,
for instance, as is done in the \code{\link[=answer_as_json]{answer_as_json()}} function}

\item{\code{json_type}}{The type of JSON mode to use (e.g., 'auto', 'openai', 'ollama', 'ellmer', or 'text-based').
Using 'auto' or having this field not set, the api_type field will be used to
determine the JSON mode during the \code{\link[=answer_as_json]{answer_as_json()}} function. If this field
is set, this will override the api_type field for JSON mode determination.
(Note: this determination only happens when the 'type' argument in
\code{\link[=answer_as_json]{answer_as_json()}} is also set to 'auto'.)}

\item{\code{tool_type}}{The type of tool use mode to use (e.g., 'auto', 'openai', 'ollama', 'ellmer', or 'text-based').
Using 'auto' or having this field not set, the api_type field will be used to
determine the tool use mode during the \code{\link[=answer_using_tools]{answer_using_tools()}} function. If this field
is set, this will override the api_type field for tool use mode determination
(Note: this determination only happens when the 'type' argument in
\code{\link[=answer_using_tools]{answer_using_tools()}} is also set to 'auto'.)}

\item{\code{handler_fns}}{A list of functions that will be called after the completion of a chat.
See \verb{$add_handler_fn()}}

\item{\code{stream_callback}}{Optional callback function for streaming tokens/chunks. If set, this function will be
called with arguments \verb{(chunk, meta)} where \code{chunk} is the latest
streamed text chunk and \code{meta} is a list with fields including \code{llm_provider},
\code{chat_history}, and \code{partial_response} to provide more context about the current
prompt that is being replied to. You may use this to implement custom streaming behaviour;
see \verb{vignette(}"streaming_shiny_ipc", "tidyprompt")` for an example of how this
function is used to stream a non-blocking async LLM response to a Shiny app using the
'ipc' package.}

\item{\code{pre_prompt_wraps}}{A list of prompt wraps that will be applied to any prompt evaluated
by this \linkS4class{llm_provider} object, before any prompt-specific
prompt wraps are applied. See \verb{$add_prompt_wrap()}.
This can be used to set default behavior for all prompts
evaluated by this \linkS4class{llm_provider} object.}

\item{\code{post_prompt_wraps}}{A list of prompt wraps that will be applied to any prompt evaluated
by this \linkS4class{llm_provider} object, after any prompt-specific
prompt wraps are applied. See \verb{$add_prompt_wrap()}.
This can be used to set default behavior for all prompts
evaluated by this \linkS4class{llm_provider} object.}
}
\if{html}{\out{</div>}}
}
\section{Methods}{
\subsection{Public methods}{
\itemize{
\item \href{#method-LlmProvider-new}{\code{llm_provider-class$new()}}
\item \href{#method-LlmProvider-set_parameters}{\code{llm_provider-class$set_parameters()}}
\item \href{#method-LlmProvider-complete_chat}{\code{llm_provider-class$complete_chat()}}
\item \href{#method-LlmProvider-add_handler_fn}{\code{llm_provider-class$add_handler_fn()}}
\item \href{#method-LlmProvider-set_handler_fns}{\code{llm_provider-class$set_handler_fns()}}
\item \href{#method-LlmProvider-add_prompt_wrap}{\code{llm_provider-class$add_prompt_wrap()}}
\item \href{#method-LlmProvider-apply_prompt_wraps}{\code{llm_provider-class$apply_prompt_wraps()}}
\item \href{#method-LlmProvider-clone}{\code{llm_provider-class$clone()}}
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-new"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-new}{}}}
\subsection{Method \code{new()}}{
Create a new \linkS4class{llm_provider} object
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$new(
  complete_chat_function,
  parameters = list(),
  verbose = TRUE,
  url = NULL,
  api_key = NULL,
  api_type = "unspecified"
)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{complete_chat_function}}{Function that will be called by the \linkS4class{llm_provider} to complete a chat.
This function should take a list containing at least '$chat_history'
(a data frame with 'role' and 'content' columns) and return a response
object, which contains:
\itemize{
\item 'completed': A dataframe with 'role' and 'content' columns,
containing the completed chat history

\item 'http': A list containing a list 'requests' and a list 'responses',
containing the HTTP requests and responses made during the chat completion
}}

\item{\code{parameters}}{A named list of parameters to configure the \linkS4class{llm_provider}.
These parameters may be appended to the request body when interacting with
the LLM provider.
For example, the \code{model} parameter may often be required.
The 'stream' parameter may be used to indicate that the API should stream.
Parameters should not include the chat_history, or 'api_key' or 'url', which
are handled separately by the \linkS4class{llm_provider} and '$complete_chat()'.
Parameters should also not be set when they are handled by prompt wraps}

\item{\code{verbose}}{A logical indicating whether interaction with the LLM
provider should be printed to the console}

\item{\code{url}}{The URL to the LLM provider API endpoint for chat completion
(typically required, but may be left NULL in some cases, for instance
when creating a fake LLM provider)}

\item{\code{api_key}}{The API key to use for authentication with the LLM
provider API (optional, not required for, for instance, Ollama)}

\item{\code{api_type}}{The type of API to use (e.g., "openai", "ollama").
This is used to determine certain specific behaviors for different APIs
(see for example the \code{\link[=answer_as_json]{answer_as_json()}} function)}
}
\if{html}{\out{</div>}}
}
\subsection{Returns}{
A new \linkS4class{llm_provider} R6 object
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-set_parameters"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-set_parameters}{}}}
\subsection{Method \code{set_parameters()}}{
Helper function to set the parameters of the \linkS4class{llm_provider}
object.
This function appends new parameters to the existing parameters
list.
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$set_parameters(new_parameters)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{new_parameters}}{A named list of new parameters to append to the
existing parameters list}
}
\if{html}{\out{</div>}}
}
\subsection{Returns}{
The modified \linkS4class{llm_provider} object
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-complete_chat"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-complete_chat}{}}}
\subsection{Method \code{complete_chat()}}{
Sends a chat history (see \code{\link[=chat_history]{chat_history()}}
for details) to the LLM provider using the configured \verb{$complete_chat()}.
This function is typically called by \code{\link[=send_prompt]{send_prompt()}} to interact with the LLM
provider, but it can also be called directly.
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$complete_chat(input)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{input}}{A string, a data frame which is a valid chat history
(see \code{\link[=chat_history]{chat_history()}}), or a list containing a valid chat history under key
'$chat_history'}
}
\if{html}{\out{</div>}}
}
\subsection{Returns}{
The response from the LLM provider
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-add_handler_fn"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-add_handler_fn}{}}}
\subsection{Method \code{add_handler_fn()}}{
Helper function to add a handler function to the
\linkS4class{llm_provider} object.
Handler functions are called after the completion of a chat and can be
used to modify the response before it is returned by the \linkS4class{llm_provider}.
Each handler function should take the response object
as input (first argument) as well as 'self' (the \linkS4class{llm_provider}
object) and return a modified response object.
The functions will be called in the order they are added to the list.
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$add_handler_fn(handler_fn)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{handler_fn}}{A function that takes the response object plus
'self' (the \linkS4class{llm_provider} object) as input and
returns a modified response object}
}
\if{html}{\out{</div>}}
}
\subsection{Details}{
If a handler function returns a list with a 'break' field set to \code{TRUE},
the chat completion will be interrupted and the response will be returned
at that point.
If a handler function returns a list with a 'done' field set to \code{FALSE},
the handler functions will continue to be called in a loop until the 'done'
field is not set to \code{FALSE}.
}

}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-set_handler_fns"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-set_handler_fns}{}}}
\subsection{Method \code{set_handler_fns()}}{
Helper function to set the handler functions of the
\linkS4class{llm_provider} object.
This function replaces the existing
handler functions list with a new list of handler functions.
See \verb{$add_handler_fn()} for more information
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$set_handler_fns(handler_fns)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{handler_fns}}{A list of handler functions to set}
}
\if{html}{\out{</div>}}
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-add_prompt_wrap"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-add_prompt_wrap}{}}}
\subsection{Method \code{add_prompt_wrap()}}{
Add a provider-level prompt wrap template to be applied to all prompts.
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$add_prompt_wrap(prompt_wrap, position = c("pre", "post"))}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{prompt_wrap}}{A list created by \code{\link[=provider_prompt_wrap]{provider_prompt_wrap()}}}

\item{\code{position}}{One of "pre" or "post" (applied before/after prompt-specific wraps)}
}
\if{html}{\out{</div>}}
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-apply_prompt_wraps"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-apply_prompt_wraps}{}}}
\subsection{Method \code{apply_prompt_wraps()}}{
Apply all provider-level wraps to a prompt (character or tidyprompt)
and return a tidyprompt with wraps attached.
This is typically called inside \code{send_prompt()} before evaluation of
the prompt.
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$apply_prompt_wraps(prompt)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{prompt}}{A string, a chat history, a list containing
a chat history under key '$chat_history', or a \linkS4class{tidyprompt} object}
}
\if{html}{\out{</div>}}
}
}
\if{html}{\out{<hr>}}
\if{html}{\out{<a id="method-LlmProvider-clone"></a>}}
\if{latex}{\out{\hypertarget{method-LlmProvider-clone}{}}}
\subsection{Method \code{clone()}}{
The objects of this class are cloneable with this method.
\subsection{Usage}{
\if{html}{\out{<div class="r">}}\preformatted{llm_provider-class$clone(deep = FALSE)}\if{html}{\out{</div>}}
}

\subsection{Arguments}{
\if{html}{\out{<div class="arguments">}}
\describe{
\item{\code{deep}}{Whether to make a deep clone.}
}
\if{html}{\out{</div>}}
}
}
}
