Language models

gptr logo

Use peter() with a prompt to run a language model agent and receive a session. The agent can inspect objects already loaded in your R environment, compute on them, and reuse named results on later turns. Choosing an API, CLI or Ollama model changes the model route; its gptr R tool still works in the selected live workspace. The model receives bounded descriptions and tool results, which may include data values or plots, rather than an automatic serialization of the full dataset. Execution model explains copies, separate workers and file-backed objects.

The same call works in a function, a loop or a script. This guide executes only scripted fake providers; examples that connect to real services are shown without running them.

Choose and connect a model

gptr_providers() lists configured routes and credential sources without making a request. gptr_models() searches the catalog already available on disk. Neither listing proves that an account can make a model request. check = TRUE probes provider reachability and CLI versions; refresh = TRUE updates a catalog or asks a local server which models it has installed.

gptr_providers(check_login = TRUE) adds CLI-reported signed in, not signed in or unknown states by running supported local status commands. It does not make a model request or verify credentials online. This optional probe is separate from check = TRUE; both default to FALSE, so the default listing starts no processes. A Codex API-key login can count as signed in, so login status does not establish subscription billing.

gptr_providers()
gptr_models("sonnet")
gptr_models(provider = "openai")
gptr_providers(check = TRUE)
gptr_providers(check_login = TRUE)

Select a canonical "provider/model" reference to make the route explicit. Catalog aliases such as sonnet also work. For a default, use gptr_config(model = ..., .scope = "user"); pass model = ... to override it for one call. Configuration explains scope and precedence.

API providers

Obtain a key from the provider, then put it in the environment of your R process or an existing private .env file. gptr_env() loads that file, registers values for redaction and reports names and fingerprints. It leaves an existing environment variable alone unless override = TRUE. Keep the file out of version control.

Route Credential variable Example reference
Anthropic ANTHROPIC_API_KEY "anthropic/claude-sonnet-5-5"
OpenAI OPENAI_API_KEY "openai/gpt-6-sol"
Google Gemini GEMINI_API_KEY or GOOGLE_API_KEY "google/gemini-3.8-flash"
OpenRouter OPENROUTER_API_KEY Choose a reference from gptr_models(provider = "openrouter")
Hosted System 1 TYPESAFE_API_KEY (jev-key is a .env alias) "typesafe/jev-latest"
library(gptr)
gptr_env("~/keys/models.env")
gptr_config(model = "openai/gpt-6-sol", .scope = "user")
session = peter("Explain the relationship between mpg and wt.", mtcars)
session$text

At first interactive use of a remote route, gptr asks you to acknowledge the data sent to it. For unattended jobs, acknowledge the specific provider beforehand at user scope:

gptr_config(egress = utils::modifyList(gptr_config()$egress, list(openai = "ack")),
            .scope = "user")

This covers automatic context; it does not pre-approve tool actions. Read ?gptr_egress for the request contents and ?gptr_security before using sensitive data. gptr_login("openrouter") offers an interactive login; gptr_login("anthropic", method = "key") offers masked key entry. These credentials are separate from a command-line tool’s sign-in.

An OpenAI-compatible service can use the existing completions adapter. Register its endpoint, credential variable and the model metadata supplied by your service:

off = gptr_register(gptr_provider(
  "work", api = "openai-completions", base_url = "https://llm.example.org/v1",
  auth = "WORK_API_KEY",
  models = list(list(id = "work-model", context = 32000, max_output = 4000,
                     tool_call = TRUE))
))
peter("Summarize these data.", mtcars, model = "work/work-model")
off()  # remove this process-lifetime provider registration

Declare features only when your service supports them. Endpoint compatibility alone does not establish tool, image or reasoning support. More built-in compatible routes appear in gptr_providers(); ?gptr_provider documents registration and compatibility fields.

Azure OpenAI and Amazon Bedrock

The built-in Azure route reads AZURE_OPENAI_API_KEY and AZURE_OPENAI_ENDPOINT. Give the resource endpoint, such as https://your-resource.openai.azure.com; gptr adds /openai/v1 and sends the key in the api-key header. The model sent to Azure is your deployment name. Declare that deployment and its real capacities in provider settings:

gptr_env("~/keys/azure.env")  # AZURE_OPENAI_API_KEY and AZURE_OPENAI_ENDPOINT
azure_model = list(id = "analysis-chat", context = 32000, max_output = 4000,
                   tool_call = TRUE)
gptr_config(
  providers = list(azure = list(models = list(azure_model))),
  .scope = "session"
)
session = peter("Summarize these data.", mtcars, model = "azure/analysis-chat")

Replace analysis-chat and the limits with your deployment’s metadata; declare tool_call only when supported. Alternatively, AZURE_OPENAI_DEPLOYMENT_NAME_MAP maps a declared model id to its deployment using model-id=deployment-name pairs separated by commas.

The built-in Bedrock route uses AWS_BEARER_TOKEN_BEDROCK with the runtime’s OpenAI-compatible API. AWS_REGION, then AWS_DEFAULT_REGION, selects the region; the default is us-east-1. Its endpoint is https://bedrock-runtime.<region>.amazonaws.com/openai/v1. Choose a model your account can use through that API and declare its id and capacities:

gptr_env("~/keys/bedrock.env")  # AWS_BEARER_TOKEN_BEDROCK and AWS_REGION
bedrock_model = list(id = "your-bedrock-model-id", context = 32000, max_output = 4000,
                     tool_call = TRUE)
gptr_config(
  providers = list(bedrock = list(models = list(bedrock_model))),
  .scope = "session"
)
session = peter("Summarize these data.", mtcars,
                model = "bedrock/your-bedrock-model-id")

Replace the illustrative metadata with your service’s values. This built-in route does not implement AWS SigV4 signing, AWS profile credentials or the general Bedrock Converse API. An AWS credentials file alone therefore does not authenticate it, and the route does not imply support for every Bedrock model. These remote providers need the egress acknowledgment described above, using provider ids azure and bedrock.

Subscription command-line tools

Install and sign in to the claude or codex tool outside gptr, following that tool’s own setup. The executable must be on PATH, or you can give its path with the gptr.cli_path option. Then choose model = "claude-cli" (alias claude_code) or model = "codex".

options(gptr.cli_path = list(claude = "/path/to/claude", codex = "/path/to/codex"))
gptr_providers(check = TRUE)
session = peter("Inspect the columns of mtcars.", mtcars, model = "codex")

These calls run a child process. The built-in claude-cli route uses the Claude Code CLI’s signed-in plan/OAuth authentication and refuses API-key billing. For API-key use, explicitly choose the direct anthropic provider. The Codex route uses the CLI’s active authentication and billing. Live R access goes through gptr’s MCP permission gate; the Codex route needs the suggested packages httpuv, later and openssl. First use asks for an acknowledgment. gptr checks required CLI flags and rejects incompatible versions. The Claude plan route is experimental and opt-in; review ?gptr_security and the provider’s terms before choosing it.

Local Ollama models

Run Ollama separately and install the model you intend to use. Discover the installed models, then copy a returned reference into the call:

local_models = gptr_models(provider = "ollama", refresh = TRUE)
local_models
session = peter("Inspect mtcars and suggest a plot.", mtcars,
                model = "ollama/qwen3:1.7b")

The default server is http://127.0.0.1:11434/v1. For another local endpoint, configure its base_url explicitly with gptr_config(providers = list(ollama = list(base_url = ...)), .scope = "user"). gptr verifies installed-model capabilities and inference locality. Its default local_only = TRUE rejects cloud selectors, remote markers and ambiguous locality; it does not install, start or update Ollama, pull models or fall back to a cloud route.

Conversational models return sessions. Clef and Clef Flash are native decision models, require Ollama 0.35.1 or later, and return logical, choice or score vectors. Their calls do not run an agent conversation. See System 1 decisions. A local model does not keep a later cloud call or network tool local.

Work with a session

Ask for the analysis, then steer the same session:

session = peter("Fit mpg from wt in mtcars. Save the model as fit.", mtcars)
session |> peter("Explain how weight relates to fuel economy.")
session$text

gptr_fork(session) explicitly branches the conversation into a new session with an overlay workspace. A model switch continues the existing history; a separate peter() call starts a new session:

library(gptr)
fake = gptr_fake_provider(list("Weight is associated with lower fuel economy."))
other = gptr_fake_provider(list("An association does not establish causation."),
                           name = "other")
session = peter("Describe how mpg relates to wt.", mtcars, model = fake)
session |> peter("Add a caveat.", model = other)
#> An association does not establish causation.
#> idle . other/other-1 . 2 turns . 3.3k tokens . $0.0000 . s86baf8f136

Put calls in functions and scripts

Inside a function, peter() works in the function’s own frame, so new objects stay local. Return the value Peter selected with ordinary R:

numeric_means = function(data) {
  session = peter("Compute and return each numeric-column mean.", data)
  session$value
}
Offline function example
numeric_means = function(data) {
  fake = gptr_fake_provider(list(
    list(tool = "r", input = list(code = paste(
      "numeric = vapply(data, is.numeric, logical(1))",
      "means = colMeans(data[numeric])",
      "gptr_return(means)", sep = "\n"
    ))),
    "The numeric-column means are ready."
  ))
  session = peter("Compute and return each numeric-column mean.", data,
                  model = fake, mode = auto)
  session$value
}
numeric_means(mtcars[c("mpg", "wt")])
#>      mpg       wt
#> 20.09062  3.21725

In a real script, replace the fake provider with an explicit model reference. Use manual when a person can answer permissions; for an unattended job, choose appropriate permission rules or an explicit mode before running it. auto still retains critical and secret guards. A permission question with nobody present raises gptr_error_permission and carries the blocked session as e$session.

session = tryCatch(
  peter("Fit mpg on wt and return the coefficients.", mtcars,
        model = "openai/gpt-6-sol", mode = auto, budget = list(cost = 1, turns = 10)),
  gptr_error_permission = function(e) {
    message(conditionMessage(e))
    e$session
  }
)
session$status

gptr_usage(session) reports tokens and costs. gptr_prompt(session) inspects the frozen prompt, declared tools, first message and token estimates; it does not report the current request’s budgets. Catalog prices and estimates are planning aids, and missing usage remains unknown. See Token efficiency for limits and Script as history for recording and replay that removes repeated model calls.