Runs language model agents in an existing 'R' session, where generated code can inspect and modify objects already in memory. The peter() function supports interactive chat and programmatic calls. Conversational models use tools and return session objects; typed decision models return logical, character or numeric vectors with associated model probabilities. Supports the 'Anthropic' < https://platform.claude.com/docs/en/api/overview>, 'OpenAI' < https://developers.openai.com/api/reference/overview> and 'Google Gemini' < https://ai.google.dev/gemini-api/docs> APIs, 'OpenAI'-compatible endpoints, local 'Ollama' < https://ollama.com> models, and the 'Claude Code' and 'Codex' command line tools. Decision models include 'Jev', hosted by 'TypeSafe AI' < https://docs.typesafe.ai/introduction>, and the local 'Clef'. Top-level agent calls and their executed code can be recorded in 'R' scripts, 'R Markdown' and 'Quarto' documents, or 'Jupyter' notebooks. Recorded 'R' scripts can be replayed without model calls when the required inputs and packages are available.

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 session
Start 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.