---
title: "Tools and artifacts"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Tools and artifacts}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
The model usually works through the `r` tool and calls helpers inside that R code. You can call
the same helpers from the R console. A model call passes permission checks; a helper you call
yourself executes directly. [Configuration](configuration.html) explains modes and permissions.
Use `peter$help("member")` for a helper's full schema and `peter$search("words")` to discover
capabilities. R functions, file helpers, language bridges, artifact creation and MCP share the
namespace. Plugin tools use `peter$namespace$name(...)`; MCP tools use
`peter$mcp$server$tool(...)`. There is no general `peter$r()` member: ordinary R code is already
the model's `r` input.
## Inspect objects, files and output
Start with a request in ordinary language. Choose a model as described in
[Language models](language-models.html), then use the objects in your R session:
``` r
library(gptr)
session = peter("Describe the first six rows of mtcars.")
session
```
This is the helper the model calls:
``` r
library(gptr)
peter$describe(head(mtcars), budget = 60L)
#> 6 x 11, 2.9 KB
#> mpg:dbl cyl:dbl disp:dbl hp:dbl drat:dbl wt:dbl qsec:dbl vs:dbl am:dbl gear:dbl carb:dbl
```
These are the object and output helper signatures:
``` r
peter$describe(x, budget = 150L)
peter$help(name, package = NULL, budget = 800L)
peter$search(words, limit = 8L)
peter$plot(which = NULL, width = 1000L, height = 700L)
peter$out(id, stream = c("stdout", "stderr"), lines = NULL)
```
`describe()` returns a compact object description. `help()` also accepts an R help topic,
`"namespace/member"` or `"server/tool"`. `search()` returns names, kinds, signatures and scores.
`plot()` attaches the current plot, or a stored plot selected by `which`, to a running `r` result;
it returns invisibly. `out()` retrieves full captured text by output id, optionally only selected
lines. Display budgets limit what is printed, not the stored full output.
The file helper signatures are:
``` r
peter$read(path, offset = NULL, limit = NULL)
peter$write(path, content)
peter$edit(path, edits, replace_all = FALSE)
peter$grep(pattern, path = ".", glob = NULL, ignore_case = FALSE, fixed = FALSE,
context = 0L, limit = 100L, output = c("content", "files", "count"),
sort = c("path", "count", "mtime"))
peter$find(pattern, path = ".", sort = c("path", "mtime", "size", "relevance"),
type = "file", limit = 1000L)
peter$ls(path = ".", sort = c("name", "mtime", "size"), long = FALSE)
```
`read()` returns numbered lines and can attach supported images to a model's running `r` result.
`write()` replaces a file and returns its path invisibly. `edit()` accepts a list of exact text
replacements (`oldText`, `newText`) or a supported patch envelope. Review a write or edit before
executing it. For example:
``` r
peter$read("analysis.R", offset = 1L, limit = 40L)
peter$grep("normalization", path = "R", glob = "*.R", fixed = TRUE, output = "files")
peter$find("analysis", type = "file", sort = "relevance")
peter$ls("R", long = TRUE)
peter$edit("analysis.R", list(list(oldText = "n = 10", newText = "n = 20")))
```
`grep()` returns matching lines, file names or counts; sorting by count or modification time
applies to file and count output. `find()` supports relevance sorting when you know part of a
name. `ls()` lists directory entries. File access outside the project and protected paths can
require stronger permissions in model code.
`read`, `write`, `edit`, `grep`, `find` and `ls` also have direct model tool forms; the active
preset decides which forms are offered. The broader helper catalog stays callable inside R.
For the console's `!` inline R and file references, see
[Interactive console](interactive-console.html). To keep generated analysis code in a document,
see [Script as history](script-as-history.html).
## Shell commands and scripts
``` r
peter$sh(cmd, input = NULL, wd = ".", timeout = 120, env = NULL,
merge = FALSE, check = FALSE, max_tokens = NULL)
peter$script(path, args = character(), interpreter = NULL, ...)
```
A `cmd` vector of more than one element is a program and its arguments, without shell expansion.
A single command line is parsed directly when possible and uses a shell when it contains shell
syntax. Prefer a vector when passing paths or data. `input` accepts text, raw bytes or a data
frame; `env` supplies named environment entries and `wd` chooses the working directory.
``` r
result = peter$sh(c("Rscript", "--vanilla", "analysis.R"), timeout = 60, check = TRUE)
result$status
result$stdout
peter$script("analysis.R", args = "input.csv", timeout = 60, check = TRUE)
```
`sh()` and `script()` return a `gptr_cmd` containing captured output and status. `check = TRUE`
raises an error for a nonzero exit status. A timeout stops the child process tree. `script()`
chooses an interpreter from the file or your explicit `interpreter`, and forwards additional
options to `sh()`. Script bodies are not statically inspected as R model code, so model calls
need the corresponding execution permission. These helpers do not install missing programs.
## Background programs
``` r
peter$bg(cmd, name = NULL, stdin = FALSE, merge = TRUE)
peter$jobs(kill = FALSE)
job = peter$bg(c("Rscript", "--vanilla", "analysis.R"), name = "analysis")
job$status()
job$read(stream = "stdout", n = 20L)
job$wait(timeout = 30, until = NULL)
job$kill()
```
`bg()` returns a job handle. Output goes to files so an unread job can keep running. Set
`stdin = TRUE` only when you need `job$write(text)` to send input. `$read()` consumes unread
output; `$wait()` accepts a timeout or a matching `until` pattern. `$kill()` stops this job.
`peter$jobs()` lists these background programs; `kill = TRUE` stops the running ones.
Background gptr sessions and teams are separate workflows, described in
[Teams and background work](teams-and-background.html).
## Python, SQL and other engines
``` r
peter$py(code, name = NULL, max_rows = 10L)
peter$sql(query, name = NULL, con = NULL, n = 10L)
peter$knit(engine, code)
```
Python needs `reticulate` and an already configured Python runtime. Its interpreter persists
between calls; gptr refuses to provision Python automatically. Pass an R object, or a named list
of objects, as `name` to make them available in Python. The result holds captured output and the
last expression's representation; `$value` converts that value to R and `$error` reports a Python
error.
Data-frame conversion to Python also requires the corresponding Python support, such as pandas
for the example below. Conversion and Python computations can allocate additional memory even
when the original R object is already loaded.
``` r
py = peter$py("float(mtcars['mpg'].mean())", name = mtcars)
py$value
peter$sql("SELECT cyl, AVG(mpg) AS mpg FROM mtcars GROUP BY cyl", name = mtcars)
peter$sql("SELECT * FROM measurements", con = con, n = 5L)
peter$knit("bash", "printf 'hello\n'")
```
SQL on a supplied data frame requires `DBI` and `duckdb`; the expression label (`mtcars` here)
becomes the table name. A named list supplies multiple tables. Otherwise give a DBI connection
as `con`; without either argument, gptr looks for one unambiguous connection in the calling
environment. SQL returns all rows while printing only `n`. Temporary data-frame databases are
closed after the call.
`knit()` captures a knitr language engine's output. Shell engines use the supervised shell
helper with its timeout; Python and SQL use the helpers above. Other engines need their own
installed runtime. All model calls still pass permission checks.
## Build a versioned artifact
With a data frame called `survey` in your session, ask Peter to build a view:
``` r
peter("Create a Shiny app showing survey as a table.")
```
To version working files yourself, use:
``` r
peter$app(
id, data = character(), title = NULL, kind = "shiny",
check = TRUE, launch = interactive()
)
```
Each call creates an immutable version. The built-in kinds are `"shiny"` and `"html"`;
plugins can register other artifact types.
For Shiny, write `.gptr/artifacts//app.R` with a final `shinyApp(ui, server)` expression.
Do not call `runApp()`, change the working directory or install packages inside the app. This
complete example writes files and needs Shiny, so it is not run while building the guide:
``` r
gptr_init(".")
survey = data.frame(group = c("A", "B"), value = c(2, 5))
app_dir = file.path(".gptr", "artifacts", "survey-view")
dir.create(app_dir, recursive = TRUE, showWarnings = FALSE)
writeLines(c(
"library(shiny)",
"ui = fluidPage(tableOutput('table'))",
"server = function(input, output, session) {",
" output$table = renderTable(survey)",
"}",
"shinyApp(ui, server)"
), file.path(app_dir, "app.R"))
artifact = peter$app("survey-view", data = "survey", title = "Survey", launch = FALSE)
artifact$version
artifact$checks
gptr_artifacts("survey-view", open = TRUE)
```
`data` is a vector of object **names**. Each version serializes those objects to its own RDS
files; a launched app loads them in a separate R process. Ordinary edits to the original R
objects do not rewrite that snapshot. This uses disk space and child-process memory, so choose
the subset or summary the app needs. Edit the working `app.R` and call
`peter$app()` again to snapshot a revision into `v002/`, `v003/` and so on. The default snapshot
limit is 500 MB (`gptr.artifact_max_bytes`). Without a project workspace, artifacts use a
temporary workspace; use `gptr_init()` for work you want to retain.
See [Execution model](execution-model.html) for computation on live objects without an artifact
snapshot.
For HTML, write `page.html` in the same working directory and call
`peter$app("survey-view", kind = "html", launch = FALSE)`. HTML is served through a Shiny
wrapper too, so launching either built-in kind needs Shiny. Static HTML validation checks that
the page exists and is nonempty; it does not certify its JavaScript or external dependencies.
## Inspect, reopen and stop artifacts
``` r
gptr_artifacts("survey-view")
gptr_artifacts("survey-view", version = 1L, open = TRUE)
gptr_artifacts("survey-view", stop = TRUE)
```
The listing shows the current version, process status, URL, disk use and working path. An
individual handle includes its version, URL, status, checks and optional screenshot.
`open = TRUE` launches a stopped artifact and opens it in a browser. Selecting an older version
changes the current version and relaunches its saved snapshot. Stopping releases the process;
saved versions remain available. Stop cannot be combined with `open` or `version`.
With `check = TRUE`, gptr checks Shiny source before versioning and, when launched, checks
startup and HTTP access. A browser session check and screenshot also need `chromote` and Chrome.
Check flags are `TRUE`, `FALSE` or `NA`; skipped browser checks do not prove the interface works.
`launch = FALSE` creates a version without starting a server, and therefore cannot validate
startup or browser behavior. Read the returned checks and messages before calling an app ready.
Artifacts run in supervised child R processes on loopback addresses. Registered secrets are
removed from their environment, and launch URLs carry access tokens when secure randomness is
available. Keep URLs and data snapshots private. A child process is not an operating-system
sandbox: review its code, file access and dependencies. Model-triggered app creation requires
execution permission. The `.gptr/.gitignore` written by `gptr_init()` excludes snapshot data and
runtime files; review your repository's ignore rules before committing artifacts.
For new helpers and artifact types, see [Extending gptr](extending-gptr.html) and
[Skills and plugins](skills-and-plugins.html). For external tool families, see [MCP](mcp.html).