
gptr runs language model agents in your current R session. Agents can analyze objects already in memory and create R objects that you can inspect, reuse or modify.
gptr requires R 4.2 or later and has no compiled code. This README describes version 1.0.0.
Development version from GitHub:
if (!requireNamespace("pak", quietly = TRUE)) install.packages("pak")
pak::pak("Broccolito/gptr@main")Released version from CRAN:
install.packages("gptr")Choose one route. If packageVersion("gptr") is below
1.0.0, install from GitHub before following these examples. After
installation, load the package:
library(gptr)Choose one of the following routes before running the analysis examples.
API key. Put your provider’s key in a private
.env file. For example, the Anthropic route needs
ANTHROPIC_API_KEY:
gptr_env("~/keys/.env")
gptr_config(model = "anthropic/claude-sonnet-5-5", .scope = "user")This saves the default model for future R sessions. Use
.scope = "session" to limit a setting to the current R
process. gptr_providers() lists configured routes.
Existing CLI login. Install and sign in to Claude Code or Codex outside R, then open the chat:
peter()With no default model set, the console offers the available CLI
routes and saves your choice. Enter /exit to return to R.
CLI sign-in is separate from API credentials.
Local Ollama model. Start Ollama separately and install a chat model that supports tool calls. Select an installed model, for example:
gptr_config(model = "ollama/qwen3:1.7b", .scope = "session")gptr does not install Ollama or download models. Local-only Ollama inference is on by default; a workflow remains local only when every model and tool it uses is local.
The first interactive use of a remote provider asks you to
acknowledge the data it receives, including with
context = "none": project instructions and environment
details still go. For unattended runs, review ?gptr_egress,
then save consent for the provider beforehand:
gptr_config(egress = utils::modifyList(gptr_config()$egress, list(anthropic = "ack")),
.scope = "user")Use the provider you selected; offline scripted models and local loopback routes remain exempt (Ollama only while local-only inference is on). See Language models for setup.
With a model configured, ask for a task and continue the same agent session:
session = peter("Fit mpg on wt in mtcars and store the model as fit.", mtcars)
session |> peter("Which cars have the largest residuals in fit?")
session$text
coef(fit)The pipe adds a turn to the same conversation and reuses
fit. The returned objects have different roles:
| Object | What it contains |
|---|---|
session |
The agent conversation, status and usage, as a
gptr_session |
session$text |
The latest text answer |
fit |
The fitted R model, available in your workspace |
session$value holds the most recent R result selected
with gptr_return(); a turn that selects no result leaves
that value unchanged.
At the console, agent code runs in your R workspace. R computes on the full objects, while the model receives size-limited descriptions, previews and tool output that may include data values. R’s usual memory allocation and copy-on-modify rules apply. See Execution model and Data sent to providers.
In the default manual mode, actions classified as
read-only run directly and actions classified as changes ask for
approval, unless a permission rule applies; an allow rule never approves
a critical action. The check is advisory and provides no sandbox; see Security
considerations or ?gptr_security in R.
Choose a recording file before starting the calls you want to keep.
This example records a new analysis using R’s built-in
mtcars data:
gptr_doc("analysis.R")
session = peter("Fit mpg on wt in mtcars and store the model as fit.")
session |> peter("Summarize the residuals in fit.")
gptr_doc(FALSE)gptr writes eligible top-level calls and their executed R code into
analysis.R, with model and execution metadata. These are
local files you can review and version with your analysis. In a new R
session, replay the recorded code:
library(gptr)
gptr_source("analysis.R", replay = "replay")Replay makes no model calls. It executes the recorded R code, including its side effects, and requires that code’s input data, files and packages.
To ask the model again, use
gptr_source("analysis.R", replay = "live");
model = picks your own model. The new run can produce
different code or results. gptr_export() can turn an
eligible recorded .R file into an ordinary R script.
Recording also supports R Markdown, Quarto and Jupyter. See Record, replay and export for document setup, recording limits and export requirements.
A decision model returns one answer per input: a logical value, a
label selected with choices, or a numeric score defined by
levels. The selected model type determines whether
peter() returns a decision vector or an agent session.
This example uses hosted Jev and requires
TYPESAFE_API_KEY, which gptr_env() can load
from your key file:
abstracts = c("We randomized 200 adults to drug or placebo.",
"We followed 5000 nurses for 20 years.")
is_rct = peter("Is this a randomized trial?", abstracts, model = "jev")
is_rct
gptr_prob(is_rct)is_rct is a logical vector. Here,
gptr_prob() returns the model’s probability of
TRUE for each abstract. It does not establish the
probability that a classification is correct.
Local Clef and Clef Flash provide typed decisions through Ollama 0.35.1 or later. gptr calls typed decision models System 1 and conversational agents System 2. See Typed decisions for scores, uncertainty, calibration and a complete offline example.
gptr_tailor() builds a harness, a function you call
exactly like peter(), with fixed arguments, your own hard
rules and coaching (a note, skills, a review). gptr_coach()
improves the coaching by running your task in separate R processes and
keeps a change only when the new run passes gptr’s checks and your
check. Rules and coaching never loosen permission checks. A
gptr_coach() call runs your task several times (4 runs and
3 coach sessions by default) and takes minutes.
auto_peter = gptr_tailor(peter, mode = "auto")
slope_peter = gptr_coach("Regress mpg on wt in mtcars; store the slope as b.", mtcars,
harness = auto_peter, check = function(r) is.numeric(r$objects$b))
slope_peter("Regress mpg on hp in mtcars; store the slope as b.", mtcars)
saveRDS(slope_peter, "slope_peter.rds")
slope_peter = gptr_tailor(readRDS("slope_peter.rds")) # load and check it in a later sessionStart with Getting
started; its examples run offline with a scripted
gptr_fake_provider(). With a CRAN install, open it in R
with vignette("getting-started", package = "gptr").
The name honors Peter Naur’s work on readable language definitions and Peter Cathcart Wason’s research with Jonathan Evans on reasoning. In Naur’s spirit, gptr records sessions as runnable documents. System 1 and System 2 name software roles in gptr; they imply nothing about human cognition. See Why Peter? for the history and sources.
gptr 1.0.0 is a rewrite. get_response() and
dataframe_to_text() were removed: use
peter("your prompt")$text and pass a data frame to
peter() as context. See NEWS.md.
If pak reports Subprocess is busy or cannot start, or
loading gptr reports a missing or corrupt gptr.rdb, restart
R and reinstall before loading the package. You can also install from
GitHub with remotes::install_github("Broccolito/gptr") if
remotes is installed.
gptr is licensed under the Apache License 2.0. Third-party notices are in inst/COPYRIGHTS.
gptr was inspired by Mario Zechner’s ‘pi’ coding agent. The tool descriptions, edit guidelines and prompt-template grammar are derived from ‘pi’, the model catalog from models.dev and the secret patterns from gitleaks, and the System 1 emulation prompt follows TypeSafe AI’s system-one-adapter-python. All four are MIT-licensed. Ideas came from ‘ellmer’, ‘tidyllm’, ‘btw’ and ‘mcptools’, none of which gptr depends on. Anthropic, OpenAI, Google, TypeSafe AI, Ollama and the vendors of the command-line tools are third-party services; gptr is not affiliated with or endorsed by them.